﻿using Emgu.CV;
using Emgu.CV.Structure;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using Vtron.LEDCorrective.Domain;
using Vtron.LEDCorrective.Domain.LEDSender;
using Vtron.LEDCorrective.Infrastructure;

namespace Vtron.LEDCorrective.Core
{
    public sealed class CorrectiveEngine
    {
        private static readonly CorrectiveEngine instance = new CorrectiveEngine();
        public static CorrectiveEngine Instance
        {
            get
            {
                return instance;
            }
        }

        private const int LEDCOLORBIT = 65535;
        private Guid id = Guid.Empty;
        private int resolWidth;
        private int resolHeight;
        private int scaleColumn;
        private int scaleRow;
        private int partitionColumn;
        private int partitionRow;
        private int blockColumn;
        private int blockRow;
        private int blockNum;
        private SCP_WALL_T scp_wall;
        //private int partitionNum;

        private int splitScreenColumn;
        private int splitScreenRow;
        //private int splitScreenNum;

        public int SplitScreenColumn
        {
            get { return splitScreenColumn; }
            set { splitScreenColumn = value; }
        }

        public int SplitScreenRow
        {
            get { return splitScreenRow; }
            set { splitScreenRow = value; }
        }

        //public int PartitionNum
        //{
        //    get { return partitionNum; }
        //    set { partitionNum = value; }
        //}

        private List<LEDCollection> ledCollections = new List<LEDCollection>();
        private List<LEDCollection> splitScreenLedCollections = new List<LEDCollection>();

        //private DoubleMatrix sRGB = null;
        //private DoubleMatrix sRGBInverse = null;
        private DoubleMatrix originalMaximumColor = null;
        private DoubleMatrix originalMaximumColorInverse = null;

        private DoubleMatrix targetxyY = null;

        public DoubleMatrix TargetxyY
        {
            get { return targetxyY; }
            set { targetxyY = value; }
        }

        /// <summary>
        /// 校正的唯一标识
        /// </summary>
        public Guid Id
        {
            get { return id; }
            set { id = value; }
        }

        /// <summary>
        /// 模组宽(像素)
        /// </summary>
        public int ResolWidth
        {
            get { return resolWidth; }
            set { resolWidth = value; }
        }

        /// <summary>
        /// 模组高(像素)
        /// </summary>
        public int ResolHeight
        {
            get { return resolHeight; }
            set { resolHeight = value; }
        }

        /// <summary>
        /// 墙规模列（模组）
        /// </summary>
        public int ScaleColumn
        {
            get { return scaleColumn; }
            set { scaleColumn = value; }
        }

        /// <summary>
        /// 墙规模行（模组）
        /// </summary>
        public int ScaleRow
        {
            get { return scaleRow; }
            set { scaleRow = value; }
        }

        /// <summary>
        /// 分块拍摄的行
        /// </summary>
        public int BlockColumn
        {
            get { return blockColumn; }
            set { blockColumn = value; }
        }

        /// <summary>
        /// 分块拍摄的列
        /// </summary>
        public int BlockRow
        {
            get { return blockRow; }
            set { blockRow = value; }
        }

        /// <summary>
        /// 分块拍摄的块号
        /// </summary>
        public int BlockNum
        {
            get { return blockNum; }
            set { blockNum = value; }
        }

        /// <summary>
        /// 分区像素列数
        /// </summary>
        public int PartitionColumn
        {
            get { return partitionColumn; }
            set { partitionColumn = value; }
        }

        /// <summary>
        /// 分区像素行
        /// </summary>
        public int PartitionRow
        {
            get { return partitionRow; }
            set { partitionRow = value; }
        }

        /// <summary>
        /// 墙体信息
        /// </summary>
        public SCP_WALL_T Scp_wall
        {
            get { return scp_wall; }
            set { scp_wall = value; }
        }

        /// <summary>
        /// 墙体总像素宽
        /// </summary>
        public int WallWidth
        {
            get
            {
                return resolWidth * scaleColumn;
            }
        }

        /// <summary>
        /// 墙体总像素高
        /// </summary>
        public int WallHeight
        {
            get
            {
                return resolHeight * scaleRow;
            }
        }

        /// <summary>
        /// 横向分割块数
        /// </summary>
        public int SeparateColumn
        {
            get
            {
                return (int)Math.Ceiling((double)resolWidth * scaleColumn / partitionColumn);
            }
        }

        /// <summary>
        /// 纵向分割块数
        /// </summary>
        public int SeparateRow
        {
            get
            {
                return (int)Math.Ceiling((double)resolHeight * scaleRow / partitionRow);
            }
        }

        /// <summary>
        /// 分区总数
        /// </summary>
        public int PartitionCount
        {
            get
            {
                return SeparateColumn * SeparateRow;
            }
        }

        /// <summary>
        /// 横向分屏分割块数
        /// </summary>
        public int SplitScreenSeparateColumn
        {
            get
            {
                return (int)Math.Ceiling((double)resolWidth * scaleColumn / splitScreenColumn);
            }
        }

        /// <summary>
        /// 纵向分屏分割块数
        /// </summary>
        public int SplitScreenSeparateRow
        {
            get
            {
                return (int)Math.Ceiling((double)resolHeight * scaleRow / splitScreenRow);
            }
        }

        /// <summary>
        /// 分屏总数
        /// </summary>
        public int SplitScreenCount
        {
            get
            {
                return SplitScreenSeparateColumn * SplitScreenSeparateRow;
            }
        }

        /// <summary>
        /// 分区LED点集合
        /// </summary>
        public List<LEDCollection> LedCollections
        {
            get
            {
                return ledCollections;
            }
        }

        /// <summary>
        /// 分屏LED点集合
        /// </summary>
        public List<LEDCollection> SplitScreenLedCollections
        {
            get
            {
                return splitScreenLedCollections;
            }
        }

        private int picId = 0;

        public int PicId
        {
            get { return picId; }
            set { picId = value; }
        }

        private DoubleMatrix targetxyYMeasure = null;

        public DoubleMatrix TargetxyYMeasure
        {
            get { return targetxyYMeasure; }
            set { targetxyYMeasure = value; }
        }

        private DoubleMatrix targetxyYsRGB = null;

        public DoubleMatrix TargetxyYsRGB
        {
            get { return targetxyYsRGB; }
            set { targetxyYsRGB = value; }
        }

        private DoubleMatrix targetxyYaRGB = null;

        public DoubleMatrix TargetxyYaRGB
        {
            get { return targetxyYaRGB; }
            set { targetxyYaRGB = value; }
        }

        private CorrectiveMode correctiveMode = CorrectiveMode.Brightness;

        public CorrectiveMode CorrectiveMode
        {
            get { return correctiveMode; }
            set { correctiveMode = value; }
        }

        public CorrectiveEngine()
        {
            blockColumn = 1;
            blockRow = 1;
            targetxyYMeasure = new double[,]{ { 0.683, 0.19, 0.135 }, 
                                            { 0.305, 0.71, 0.088 }, 
                                            { 88, 155, 50 } };
            targetxyYsRGB = new double[,]{ { 0.64, 0.3, 0.15 }, 
                                         { 0.3, 0.6, 0.06 }, 
                                         { 88, 155, 50 } };
            targetxyYaRGB = new double[,]{ { 0.64, 0.21, 0.15 }, 
                                         { 0.33, 0.71, 0.06 }, 
                                         { 80, 155, 43 } };
            targetxyY = new double[,]{ { 0, 0, 0 }, 
                                       { 0, 0, 0 }, 
                                       { 0, 0, 0 } };
            //sRGB = new double[,]{ { 0.412453, 0.35758, 0.180423 }, 
            //                      { 0.212671, 0.715159, 0.072169 }, 
            //                      { 0.019334, 0.119194, 0.950227 } };
            //sRGBInverse = sRGB.Inverse;
            originalMaximumColor = new double[,] { { 255, 0, 0 }, 
                                                   { 0, 255, 0 }, 
                                                   { 0, 0, 255 } };
            originalMaximumColorInverse = originalMaximumColor.Inverse;

            Id = Guid.NewGuid();
        }

        DoubleMatrix targetXYZ = null;

        DoubleMatrix pRGB = new DoubleMatrix();
        DoubleMatrix pRGBInverse = null;

        /// <summary>
        /// 从采集数据中计算分区校正补偿系数
        /// </summary>
        /// <param name="column">分区所在列数</param>
        /// <param name="row">分区所在行数</param>
        /// <param name="partitionNum">分区号码</param>
        public void CountOffset(int partitionNum)
        {
            if (correctiveMode == CorrectiveMode.Brightness)
            {
                BrightnessAutoCountOffset(partitionNum);
            }
            else if (correctiveMode == CorrectiveMode.Chroma)
            {
                ChromaAutoCountOffset(partitionNum);
            }
        }

        private void BrightnessAutoCountOffset(int partitionNum)
        {
            LEDCollection ledCollection = SetORGBAndPRGB(partitionNum);

            double rY = 0;
            double gY = 0;
            double bY = 0;

            DoubleMatrix[,] originalXYZ = new DoubleMatrix[partitionRow, partitionColumn];
            for (int i = 0; i < partitionRow; i++)
            {
                for (int j = 0; j < partitionColumn; j++)
                {
                    originalXYZ[i, j] = new double[3, 3];

                    originalXYZ[i, j].Columns[0] = pRGB * ledCollection.OriginalRGB[i, j].Columns[0];
                    originalXYZ[i, j].Columns[1] = pRGB * ledCollection.OriginalRGB[i, j].Columns[1];
                    originalXYZ[i, j].Columns[2] = pRGB * ledCollection.OriginalRGB[i, j].Columns[2];

                    rY += originalXYZ[i, j][0, 1];
                    gY += originalXYZ[i, j][1, 1];
                    bY += originalXYZ[i, j][2, 1];
                }
            }

            rY = rY / (partitionRow * partitionColumn);
            gY = gY / (partitionRow * partitionColumn);
            bY = bY / (partitionRow * partitionColumn);

            List<double> redYs = new List<double>();
            List<double> greenYs = new List<double>();
            List<double> blueYs = new List<double>();

            for (int i = 0; i < partitionRow; i++)
            {
                for (int j = 0; j < partitionColumn; j++)
                {
                    if (originalXYZ[i, j][0, 1] > rY * 0.3)
                    {
                        redYs.Add(originalXYZ[i, j][0, 1]);
                    }

                    if (originalXYZ[i, j][1, 1] > gY * 0.3)
                    {
                        greenYs.Add(originalXYZ[i, j][1, 1]);
                    }

                    if (originalXYZ[i, j][2, 1] > bY * 0.3)
                    {
                        blueYs.Add(originalXYZ[i, j][2, 1]);
                    }
                }
            }

            double redY = 0;
            foreach (double d in redYs)
            {
                redY += d;
            }

            redY = redY / redYs.Count();

            double greenY = 0;
            foreach (double d in greenYs)
            {
                greenY += d;
            }

            greenY = greenY / greenYs.Count();

            double blueY = 0;
            foreach (double d in blueYs)
            {
                blueY += d;
            }

            blueY = blueY / blueYs.Count();

            redY *= 0.5;
            greenY *= 0.5;
            blueY *= 0.5;

            DoubleMatrix[,] targetXYZs = new DoubleMatrix[partitionRow, partitionColumn];

            for (int i = 0; i < partitionRow; i++)
            {
                for (int j = 0; j < partitionColumn; j++)
                {
                    targetXYZs[i, j] = new double[3, 3];

                    targetXYZs[i, j][0, 0] = originalXYZ[i, j][0, 0] * redY / originalXYZ[i, j][0, 1];
                    targetXYZs[i, j][0, 2] = originalXYZ[i, j][0, 2] * redY / originalXYZ[i, j][0, 1];
                    targetXYZs[i, j][1, 0] = originalXYZ[i, j][1, 0] * greenY / originalXYZ[i, j][1, 1];
                    targetXYZs[i, j][1, 2] = originalXYZ[i, j][1, 2] * greenY / originalXYZ[i, j][1, 1];
                    targetXYZs[i, j][2, 0] = originalXYZ[i, j][2, 0] * blueY / originalXYZ[i, j][2, 1];
                    targetXYZs[i, j][2, 2] = originalXYZ[i, j][2, 2] * blueY / originalXYZ[i, j][2, 1];

                    targetXYZs[i, j][0, 1] = redY;
                    targetXYZs[i, j][1, 1] = greenY;
                    targetXYZs[i, j][2, 1] = blueY;
                }
            }

            SetKRGB(ledCollection, targetXYZs);
        }

        private void ChromaAutoCountOffset(int partitionNum)
        {
            LEDCollection ledCollection = SetORGBAndPRGB(partitionNum);

            targetXYZ = new double[3, 3];
            targetXYZ[0, 0] = targetxyY[0, 0] * targetxyY[0, 2] / targetxyY[0, 1];
            targetXYZ[0, 1] = targetxyY[0, 2];
            targetXYZ[0, 2] = (1 - targetxyY[0, 0] - targetxyY[0, 1]) * targetxyY[0, 2] / targetxyY[0, 1];

            targetXYZ[1, 0] = targetxyY[1, 0] * targetxyY[1, 2] / targetxyY[1, 1];
            targetXYZ[1, 1] = targetxyY[1, 2];
            targetXYZ[1, 2] = (1 - targetxyY[1, 0] - targetxyY[1, 1]) * targetxyY[1, 2] / targetxyY[1, 1];

            targetXYZ[2, 0] = targetxyY[2, 0] * targetxyY[2, 2] / targetxyY[2, 1];
            targetXYZ[2, 1] = targetxyY[2, 2];
            targetXYZ[2, 2] = (1 - targetxyY[2, 0] - targetxyY[2, 1]) * targetxyY[2, 2] / targetxyY[2, 1];

            DoubleMatrix[,] targetXYZs = new DoubleMatrix[partitionRow, partitionColumn];
            DoubleMatrix[,] originalXYZ = new DoubleMatrix[partitionRow, partitionColumn];

            for (int i = 0; i < partitionRow; i++)
            {
                for (int j = 0; j < partitionColumn; j++)
                {
                    originalXYZ[i, j] = new double[3, 3];

                    originalXYZ[i, j].Columns[0] = pRGB * ledCollection.OriginalRGB[i, j].Columns[0];
                    originalXYZ[i, j].Columns[1] = pRGB * ledCollection.OriginalRGB[i, j].Columns[1];
                    originalXYZ[i, j].Columns[2] = pRGB * ledCollection.OriginalRGB[i, j].Columns[2];

                    targetXYZs[i, j] = new double[,]{{targetXYZ[0,0],targetXYZ[1,0],targetXYZ[2,0]},
                                                     {targetXYZ[0,1],targetXYZ[1,1],targetXYZ[2,1]},
                                                     {targetXYZ[0,2],targetXYZ[1,2],targetXYZ[2,2]}};

                    if (targetXYZs[i, j][0, 0] > originalXYZ[i, j][0, 0])
                    {
                        targetXYZs[i, j][0, 0] = originalXYZ[i, j][0, 0];
                    }
                    if (targetXYZs[i, j][1, 0] > originalXYZ[i, j][1, 0])
                    {
                        targetXYZs[i, j][1, 0] = originalXYZ[i, j][1, 0];
                    }
                    if (targetXYZs[i, j][2, 0] > originalXYZ[i, j][2, 0])
                    {
                        targetXYZs[i, j][2, 0] = originalXYZ[i, j][2, 0];
                    }

                    if (targetXYZs[i, j][0, 1] > originalXYZ[i, j][0, 1])
                    {
                        targetXYZs[i, j][0, 1] = originalXYZ[i, j][0, 1];
                    }
                    if (targetXYZs[i, j][1, 1] > originalXYZ[i, j][1, 1])
                    {
                        targetXYZs[i, j][1, 1] = originalXYZ[i, j][1, 1];
                    }
                    if (targetXYZs[i, j][2, 1] > originalXYZ[i, j][2, 1])
                    {
                        targetXYZs[i, j][2, 1] = originalXYZ[i, j][2, 1];
                    }

                    if (targetXYZs[i, j][0, 2] > originalXYZ[i, j][0, 2])
                    {
                        targetXYZs[i, j][0, 2] = originalXYZ[i, j][0, 2];
                    }
                    if (targetXYZs[i, j][1, 2] > originalXYZ[i, j][1, 2])
                    {
                        targetXYZs[i, j][1, 2] = originalXYZ[i, j][1, 2];
                    }
                    if (targetXYZs[i, j][2, 2] > originalXYZ[i, j][2, 2])
                    {
                        targetXYZs[i, j][2, 2] = originalXYZ[i, j][2, 2];
                    }
                }
            }

            SetKRGB(ledCollection, targetXYZs);
        }

        private LEDCollection SetORGBAndPRGB(int partitionNum)
        {
            if (partitionColumn == 0 || partitionRow == 0)
            {
                throw new CorrectiveException("分区的行或列不能为零。");
            }

            LEDCollection ledCollection = ledCollections[partitionNum - 1];

            DoubleMatrix celiang = new double[,]{ { 299, 56.28378, 65 }, 
                                                  { 130, 245, 40 }, 
                                                  { 4.33, 29.7973, 395 } };

            for (int i = 0; i < partitionRow; i++)
            {
                for (int j = 0; j < partitionColumn; j++)
                {
                    ledCollection.OriginalRGB[i, j][0, 1] = ledCollection.OriginalRGB[i, j][0, 0] * 130 / 299;
                    ledCollection.OriginalRGB[i, j][0, 2] = ledCollection.OriginalRGB[i, j][0, 0] * 4.33 / 299;
                    ledCollection.OriginalRGB[i, j][1, 0] = ledCollection.OriginalRGB[i, j][1, 1] * 56.28378 / 245;
                    ledCollection.OriginalRGB[i, j][1, 2] = ledCollection.OriginalRGB[i, j][1, 1] * 29.7973 / 245;
                    ledCollection.OriginalRGB[i, j][2, 0] = ledCollection.OriginalRGB[i, j][2, 2] * 65 / 395;
                    ledCollection.OriginalRGB[i, j][2, 1] = ledCollection.OriginalRGB[i, j][2, 2] * 40 / 395;
                }
            }

            if (pRGB.IsEmpty)
            {
                double Rr = 0;
                double Rg = 0;
                double Rb = 0;

                double Gr = 0;
                double Gg = 0;
                double Gb = 0;

                double Br = 0;
                double Bg = 0;
                double Bb = 0;

                for (int i = 0; i < partitionRow; i++)
                {
                    for (int j = 0; j < partitionColumn; j++)
                    {
                        Rr += ledCollection.OriginalRGB[i, j][0, 0];
                        Rg += ledCollection.OriginalRGB[i, j][0, 1];
                        Rb += ledCollection.OriginalRGB[i, j][0, 2];

                        Gr += ledCollection.OriginalRGB[i, j][1, 0];
                        Gg += ledCollection.OriginalRGB[i, j][1, 1];
                        Gb += ledCollection.OriginalRGB[i, j][1, 2];

                        Br += ledCollection.OriginalRGB[i, j][2, 0];
                        Bg += ledCollection.OriginalRGB[i, j][2, 1];
                        Bb += ledCollection.OriginalRGB[i, j][2, 2];
                    }
                }

                Rr = Rr / (partitionRow * partitionColumn);
                Rg = Rg / (partitionRow * partitionColumn);
                Rb = Rb / (partitionRow * partitionColumn);

                Gr = Gr / (partitionRow * partitionColumn);
                Gg = Gg / (partitionRow * partitionColumn);
                Gb = Gb / (partitionRow * partitionColumn);

                Br = Br / (partitionRow * partitionColumn);
                Bg = Bg / (partitionRow * partitionColumn);
                Bb = Bb / (partitionRow * partitionColumn);

                DoubleMatrix minRGB = new double[,]{ { 65535, 65535, 65535 }, 
                                                  { 65535, 65535, 65535 }, 
                                                  { 65535, 65535, 65535 }};

                for (int i = 0; i < partitionRow; i++)
                {
                    for (int j = 0; j < partitionColumn; j++)
                    {
                        if (minRGB[0, 0] > ledCollection.OriginalRGB[i, j][0, 0] && ledCollection.OriginalRGB[i, j][0, 0] > ledCollection.OriginalRGB[i, j][0, 0] * 0.7)
                        {
                            minRGB[0, 0] = ledCollection.OriginalRGB[i, j][0, 0];
                        }
                        if (minRGB[1, 0] > ledCollection.OriginalRGB[i, j][1, 0] && ledCollection.OriginalRGB[i, j][1, 0] > ledCollection.OriginalRGB[i, j][1, 0] * 0.7)
                        {
                            minRGB[1, 0] = ledCollection.OriginalRGB[i, j][1, 0];
                        }
                        if (minRGB[2, 0] > ledCollection.OriginalRGB[i, j][2, 0] && ledCollection.OriginalRGB[i, j][2, 0] > ledCollection.OriginalRGB[i, j][2, 0] * 0.7)
                        {
                            minRGB[2, 0] = ledCollection.OriginalRGB[i, j][2, 0];
                        }

                        if (minRGB[0, 1] > ledCollection.OriginalRGB[i, j][0, 1] && ledCollection.OriginalRGB[i, j][0, 1] > ledCollection.OriginalRGB[i, j][0, 1] * 0.7)
                        {
                            minRGB[0, 1] = ledCollection.OriginalRGB[i, j][0, 1];
                        }
                        if (minRGB[1, 1] > ledCollection.OriginalRGB[i, j][1, 1] && ledCollection.OriginalRGB[i, j][1, 1] > ledCollection.OriginalRGB[i, j][1, 1] * 0.7)
                        {
                            minRGB[1, 1] = ledCollection.OriginalRGB[i, j][1, 1];
                        }
                        if (minRGB[2, 1] > ledCollection.OriginalRGB[i, j][2, 1] && ledCollection.OriginalRGB[i, j][2, 1] > ledCollection.OriginalRGB[i, j][2, 1] * 0.7)
                        {
                            minRGB[2, 1] = ledCollection.OriginalRGB[i, j][2, 1];
                        }

                        if (minRGB[0, 2] > ledCollection.OriginalRGB[i, j][0, 2] && ledCollection.OriginalRGB[i, j][0, 2] > ledCollection.OriginalRGB[i, j][0, 2] * 0.7)
                        {
                            minRGB[0, 2] = ledCollection.OriginalRGB[i, j][0, 2];
                        }
                        if (minRGB[1, 2] > ledCollection.OriginalRGB[i, j][1, 2] && ledCollection.OriginalRGB[i, j][1, 2] > ledCollection.OriginalRGB[i, j][1, 2] * 0.7)
                        {
                            minRGB[1, 2] = ledCollection.OriginalRGB[i, j][1, 2];
                        }
                        if (minRGB[2, 2] > ledCollection.OriginalRGB[i, j][2, 2] && ledCollection.OriginalRGB[i, j][2, 2] > ledCollection.OriginalRGB[i, j][2, 2] * 0.7)
                        {
                            minRGB[2, 2] = ledCollection.OriginalRGB[i, j][2, 2];
                        }
                    }
                }

                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        minRGB[i, j] = minRGB[i, j] * 0.9;
                    }
                }

                DoubleMatrix minRGBInverse = minRGB.Inverse;

                pRGB = celiang * minRGBInverse;
                pRGBInverse = pRGB.Inverse;
            }

            return ledCollection;
        }

        private void SetKRGB(LEDCollection ledCollection, DoubleMatrix[,] targetXYZs)
        {
            DoubleMatrix[,] TMatrix = new DoubleMatrix[partitionRow, partitionColumn];
            DoubleMatrix[,] SignalRGB = new DoubleMatrix[partitionRow, partitionColumn];
            for (int i = 0; i < partitionRow; i++)
            {
                for (int j = 0; j < partitionColumn; j++)
                {
                    DoubleMatrix targetRGB = pRGBInverse * targetXYZs[i, j];

                    TMatrix[i, j] = new double[3, 3];

                    DoubleMatrix originalRGBInverse = ledCollection.OriginalRGB[i, j].Inverse;

                    DoubleMatrix Columns0 = new double[3, 1];
                    Columns0[0, 0] = originalRGBInverse[0, 0];
                    Columns0[0, 1] = originalRGBInverse[0, 1];
                    Columns0[0, 2] = originalRGBInverse[0, 2];

                    DoubleMatrix Columns1 = new double[3, 1];
                    Columns1[0, 0] = originalRGBInverse[1, 0];
                    Columns1[0, 1] = originalRGBInverse[1, 1];
                    Columns1[0, 2] = originalRGBInverse[1, 2];

                    DoubleMatrix Columns2 = new double[3, 1];
                    Columns2[0, 0] = originalRGBInverse[2, 0];
                    Columns2[0, 1] = originalRGBInverse[2, 1];
                    Columns2[0, 2] = originalRGBInverse[2, 2];

                    TMatrix[i, j].Columns[0] = originalMaximumColor * Columns0;
                    TMatrix[i, j].Columns[1] = originalMaximumColor * Columns1;
                    TMatrix[i, j].Columns[2] = originalMaximumColor * Columns2;

                    SignalRGB[i, j] = new double[3, 3];
                    SignalRGB[i, j] = TMatrix[i, j] * targetRGB;
                    ledCollection.KRGB[i, j] = SignalRGB[i, j] * originalMaximumColorInverse;

                    for (int k = 0; k < 3; k++)
                    {
                        for (int l = 0; l < 3; l++)
                        {
                            if (ledCollection.KRGB[i, j][k, l] < 0)
                                ledCollection.KRGB[i, j][k, l] = 0;
                            else if (ledCollection.KRGB[i, j][k, l] > 1)
                                ledCollection.KRGB[i, j][k, l] = 1;
                        }
                    }

                    ledCollection.KRGB[i, j] *= LEDCOLORBIT;
                }
            }

            ledCollection.IsDone = true;
        }

        //public void CountOffset(int partitionNum)
        //{
        //    if (partitionColumn == 0 || partitionRow == 0)
        //    {
        //        throw new CorrectiveException("分区的行或列不能为零。");
        //    }

        //    //this.partitionNum = partitionNum;
        //    LEDCollection ledCollection = ledCollections[partitionNum - 1];

        //    double rr = 0;
        //    double rg = 0;
        //    double rb = 0;
        //    double gr = 0;
        //    double gg = 0;
        //    double gb = 0;
        //    double br = 0;
        //    double bg = 0;
        //    double bb = 0;

        //    int rBad = 0;
        //    int gBad = 0;
        //    int bBad = 0;

        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            if (ledCollection.OriginalRGB[i, j][0, 0] > 0)
        //            {
        //                rr += ledCollection.OriginalRGB[i, j][0, 0];
        //                rg += ledCollection.OriginalRGB[i, j][0, 1];
        //                rb += ledCollection.OriginalRGB[i, j][0, 2];
        //            }
        //            else
        //            {
        //                rBad++;
        //            }
        //            if (ledCollection.OriginalRGB[i, j][1, 1] > 0)
        //            {
        //                gr += ledCollection.OriginalRGB[i, j][1, 0];
        //                gg += ledCollection.OriginalRGB[i, j][1, 1];
        //                gb += ledCollection.OriginalRGB[i, j][1, 2];
        //            }
        //            else
        //            {
        //                gBad++;
        //            }
        //            if (ledCollection.OriginalRGB[i, j][2, 2] > 0)
        //            {
        //                br += ledCollection.OriginalRGB[i, j][2, 0];
        //                bg += ledCollection.OriginalRGB[i, j][2, 1];
        //                bb += ledCollection.OriginalRGB[i, j][2, 2];
        //            }
        //            else
        //            {
        //                bBad++;
        //            }
        //        }
        //    }

        //    rr = rr / (partitionRow * partitionColumn - rBad);
        //    rg = rg / (partitionRow * partitionColumn - rBad);
        //    rb = rb / (partitionRow * partitionColumn - rBad);

        //    gr = gr / (partitionRow * partitionColumn - gBad);
        //    gg = gg / (partitionRow * partitionColumn - gBad);
        //    gb = gb / (partitionRow * partitionColumn - gBad);

        //    br = br / (partitionRow * partitionColumn - bBad);
        //    bg = bg / (partitionRow * partitionColumn - bBad);
        //    bb = bb / (partitionRow * partitionColumn - bBad);

        //    DoubleMatrix pingjun = new double[,]{ { rr, gr, br }, 
        //                                          { rg, gg, bg }, 
        //                                          { rb, gb, bb }};

        //    DoubleMatrix pingjunInverse = pingjun.Inverse;

        //    //DoubleMatrix celiang = new double[,]{ { 2070, 413.5135, 487.5 }, 
        //    //                                      { 900, 1800, 300 }, 
        //    //                                      { 30, 218.9189, 2962.5 } };

        //    DoubleMatrix celiang = new double[,]{ { 299, 56.28378, 65 }, 
        //                                          { 130, 245, 40 }, 
        //                                          { 4.33, 29.7973, 395 } };

        //    if (pRGB.IsEmpty)
        //    {
        //        pRGB = celiang * pingjunInverse;
        //        pRGBInverse = pRGB.Inverse;
        //    }

        //    if (partitionNum == 1)
        //    {
        //        targetXYZ = new double[3, 3];
        //        targetXYZ[0, 0] = targetxyY[0, 0] * targetxyY[0, 2] / targetxyY[0, 1];
        //        targetXYZ[0, 1] = targetxyY[0, 2];
        //        targetXYZ[0, 2] = (1 - targetxyY[0, 0] - targetxyY[0, 1]) * targetxyY[0, 2] / targetxyY[0, 1];

        //        targetXYZ[1, 0] = targetxyY[1, 0] * targetxyY[1, 2] / targetxyY[1, 1];
        //        targetXYZ[1, 1] = targetxyY[1, 2];
        //        targetXYZ[1, 2] = (1 - targetxyY[1, 0] - targetxyY[1, 1]) * targetxyY[1, 2] / targetxyY[1, 1];

        //        targetXYZ[2, 0] = targetxyY[2, 0] * targetxyY[2, 2] / targetxyY[2, 1];
        //        targetXYZ[2, 1] = targetxyY[2, 2];
        //        targetXYZ[2, 2] = (1 - targetxyY[2, 0] - targetxyY[2, 1]) * targetxyY[2, 2] / targetxyY[2, 1];

        //        DoubleMatrix[,] originalXYZ = new DoubleMatrix[partitionRow, partitionColumn];

        //        for (int i = 0; i < partitionRow; i++)
        //        {
        //            for (int j = 0; j < partitionColumn; j++)
        //            {
        //                originalXYZ[i, j] = new double[3, 3];

        //                originalXYZ[i, j].Columns[0] = pRGB * ledCollection.OriginalRGB[i, j].Columns[0];
        //                originalXYZ[i, j].Columns[1] = pRGB * ledCollection.OriginalRGB[i, j].Columns[1];
        //                originalXYZ[i, j].Columns[2] = pRGB * ledCollection.OriginalRGB[i, j].Columns[2];

        //                if (targetXYZ[0, 0] > originalXYZ[i, j][0, 0])
        //                {
        //                    targetXYZ[0, 0] = originalXYZ[i, j][0, 0];
        //                }
        //                if (targetXYZ[1, 0] > originalXYZ[i, j][1, 0])
        //                {
        //                    targetXYZ[1, 0] = originalXYZ[i, j][1, 0];
        //                }
        //                if (targetXYZ[2, 0] > originalXYZ[i, j][2, 0])
        //                {
        //                    targetXYZ[2, 0] = originalXYZ[i, j][2, 0];
        //                }

        //                if (targetXYZ[0, 1] > originalXYZ[i, j][0, 1])
        //                {
        //                    targetXYZ[0, 1] = originalXYZ[i, j][0, 1];
        //                }
        //                if (targetXYZ[1, 1] > originalXYZ[i, j][1, 1])
        //                {
        //                    targetXYZ[1, 1] = originalXYZ[i, j][1, 1];
        //                }
        //                if (targetXYZ[2, 1] > originalXYZ[i, j][2, 1])
        //                {
        //                    targetXYZ[2, 1] = originalXYZ[i, j][2, 1];
        //                }

        //                if (targetXYZ[0, 2] > originalXYZ[i, j][0, 2])
        //                {
        //                    targetXYZ[0, 2] = originalXYZ[i, j][0, 2];
        //                }
        //                if (targetXYZ[1, 2] > originalXYZ[i, j][1, 2])
        //                {
        //                    targetXYZ[1, 2] = originalXYZ[i, j][1, 2];
        //                }
        //                if (targetXYZ[2, 2] > originalXYZ[i, j][2, 2])
        //                {
        //                    targetXYZ[2, 2] = originalXYZ[i, j][2, 2];
        //                }

        //                //if (targetXYZ[0, 1] > originalXYZ[i, j][0, 1])
        //                //{
        //                //    targetXYZ[0, 1] = originalXYZ[i, j][0, 1];
        //                //}

        //                //if (targetXYZ[1, 1] > originalXYZ[i, j][1, 1])
        //                //{
        //                //    targetXYZ[1, 1] = originalXYZ[i, j][1, 1];
        //                //}

        //                //if (targetXYZ[2, 1] > originalXYZ[i, j][2, 1])
        //                //{
        //                //    targetXYZ[2, 1] = originalXYZ[i, j][2, 1];
        //                //}
        //            }
        //        }

        //        //DoubleMatrix[,] targetXYZs = new DoubleMatrix[partitionRow, partitionColumn];

        //        //for (int i = 0; i < partitionRow; i++)
        //        //{
        //        //    for (int j = 0; j < partitionColumn; j++)
        //        //    {
        //        //        targetXYZs[i, j] = new double[3, 3];

        //        //        targetXYZs[i, j][0, 0] = originalXYZ[i, j][0, 0] * targetXYZ[0, 1] / originalXYZ[i, j][0, 1];
        //        //        targetXYZs[i, j][0, 2] = originalXYZ[i, j][0, 2] * targetXYZ[0, 1] / originalXYZ[i, j][0, 1];
        //        //        targetXYZs[i, j][1, 0] = originalXYZ[i, j][1, 0] * targetXYZ[1, 1] / originalXYZ[i, j][1, 1];
        //        //        targetXYZs[i, j][1, 2] = originalXYZ[i, j][1, 2] * targetXYZ[1, 1] / originalXYZ[i, j][1, 1];
        //        //        targetXYZs[i, j][2, 0] = originalXYZ[i, j][2, 0] * targetXYZ[2, 1] / originalXYZ[i, j][2, 1];
        //        //        targetXYZs[i, j][2, 2] = originalXYZ[i, j][2, 2] * targetXYZ[2, 1] / originalXYZ[i, j][2, 1];

        //        //        targetXYZs[i, j][0, 1] = targetXYZ[0, 1];
        //        //        targetXYZs[i, j][1, 1] = targetXYZ[1, 1];
        //        //        targetXYZs[i, j][2, 1] = targetXYZ[2, 1];
        //        //    }
        //        //}
        //    }
        //    DoubleMatrix targetRGB = pRGBInverse * targetXYZ;

        //    DoubleMatrix[,] TMatrix = new DoubleMatrix[partitionRow, partitionColumn];
        //    DoubleMatrix[,] SignalRGB = new DoubleMatrix[partitionRow, partitionColumn];
        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            //DoubleMatrix targetRGB = pRGBInverse * targetXYZs[i, j];

        //            TMatrix[i, j] = new double[3, 3];

        //            DoubleMatrix originalRGBInverse = ledCollection.OriginalRGB[i, j].Inverse;

        //            DoubleMatrix Columns0 = new double[3, 1];
        //            Columns0[0, 0] = originalRGBInverse[0, 0];
        //            Columns0[0, 1] = originalRGBInverse[0, 1];
        //            Columns0[0, 2] = originalRGBInverse[0, 2];

        //            DoubleMatrix Columns1 = new double[3, 1];
        //            Columns1[0, 0] = originalRGBInverse[1, 0];
        //            Columns1[0, 1] = originalRGBInverse[1, 1];
        //            Columns1[0, 2] = originalRGBInverse[1, 2];

        //            DoubleMatrix Columns2 = new double[3, 1];
        //            Columns2[0, 0] = originalRGBInverse[2, 0];
        //            Columns2[0, 1] = originalRGBInverse[2, 1];
        //            Columns2[0, 2] = originalRGBInverse[2, 2];

        //            TMatrix[i, j].Columns[0] = originalMaximumColor * Columns0;
        //            TMatrix[i, j].Columns[1] = originalMaximumColor * Columns1;
        //            TMatrix[i, j].Columns[2] = originalMaximumColor * Columns2;

        //            SignalRGB[i, j] = new double[3, 3];
        //            SignalRGB[i, j] = TMatrix[i, j] * targetRGB;
        //            ledCollection.KRGB[i, j] = SignalRGB[i, j] * originalMaximumColorInverse;

        //            for (int k = 0; k < 3; k++)
        //            {
        //                for (int l = 0; l < 3; l++)
        //                {
        //                    if (ledCollection.KRGB[i, j][k, l] < 0)
        //                        ledCollection.KRGB[i, j][k, l] = 0;
        //                    else if (ledCollection.KRGB[i, j][k, l] > 1)
        //                        ledCollection.KRGB[i, j][k, l] = 1;
        //                }
        //            }
        //            ledCollection.KRGB[i, j] *= LEDCOLORBIT;
        //        }
        //    }

        //    ledCollection.IsDone = true;
        //}

        //public void CountOffset0(int partitionNum)
        //{
        //    if (partitionColumn == 0 || partitionRow == 0)
        //    {
        //        throw new CorrectiveException("分区的行或列不能为零。");
        //    }

        //    this.partitionNum = partitionNum;
        //    LEDCollection ledCollection = ledCollections[0];

        //    double rr = 0;
        //    double rg = 0;
        //    double rb = 0;
        //    double gr = 0;
        //    double gg = 0;
        //    double gb = 0;
        //    double br = 0;
        //    double bg = 0;
        //    double bb = 0;

        //    int rBad = 0;
        //    int gBad = 0;
        //    int bBad = 0;

        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            if (ledCollection.OriginalRGB[i, j][0, 0] > 0)
        //            {
        //                rr += ledCollection.OriginalRGB[i, j][0, 0];
        //                rg += ledCollection.OriginalRGB[i, j][0, 1];
        //                rb += ledCollection.OriginalRGB[i, j][0, 2];
        //            }
        //            else
        //            {
        //                rBad++;
        //            }
        //            if (ledCollection.OriginalRGB[i, j][1, 1] > 0)
        //            {
        //                gr += ledCollection.OriginalRGB[i, j][1, 0];
        //                gg += ledCollection.OriginalRGB[i, j][1, 1];
        //                gb += ledCollection.OriginalRGB[i, j][1, 2];
        //            }
        //            else
        //            {
        //                gBad++;
        //            }
        //            if (ledCollection.OriginalRGB[i, j][2, 2] > 0)
        //            {
        //                br += ledCollection.OriginalRGB[i, j][2, 0];
        //                bg += ledCollection.OriginalRGB[i, j][2, 1];
        //                bb += ledCollection.OriginalRGB[i, j][2, 2];
        //            }
        //            else
        //            {
        //                bBad++;
        //            }
        //        }
        //    }

        //    rr = rr / (partitionRow * partitionColumn - rBad);
        //    rg = rg / (partitionRow * partitionColumn - rBad);
        //    rb = rb / (partitionRow * partitionColumn - rBad);

        //    gr = gr / (partitionRow * partitionColumn - gBad);
        //    gg = gg / (partitionRow * partitionColumn - gBad);
        //    gb = gb / (partitionRow * partitionColumn - gBad);

        //    br = br / (partitionRow * partitionColumn - bBad);
        //    bg = bg / (partitionRow * partitionColumn - bBad);
        //    bb = bb / (partitionRow * partitionColumn - bBad);

        //    DoubleMatrix pingjun = new double[,]{ { rr, gr, br }, 
        //                                          { rg, gg, bg }, 
        //                                          { rb, gb, bb }};

        //    DoubleMatrix pingjunInverse = pingjun.Inverse;

        //    //DoubleMatrix celiang = new double[,]{ { 2070, 413.5135, 487.5 }, 
        //    //                                      { 900, 1800, 300 }, 
        //    //                                      { 30, 218.9189, 2962.5 } };

        //    DoubleMatrix celiang = new double[,]{ { 299, 56.28378, 65 }, 
        //                                          { 130, 245, 40 }, 
        //                                          { 4.33, 29.7973, 395 } };

        //    DoubleMatrix pRGB = celiang * pingjunInverse;

        //    DoubleMatrix pRGBInverse = pRGB.Inverse;

        //    DoubleMatrix targetXYZ = new double[3, 3];
        //    targetXYZ[0, 0] = targetxyY[0, 0] * targetxyY[0, 2] / targetxyY[0, 1];
        //    targetXYZ[0, 1] = targetxyY[0, 2];
        //    targetXYZ[0, 2] = (1 - targetxyY[0, 0] - targetxyY[0, 1]) * targetxyY[0, 2] / targetxyY[0, 1];

        //    targetXYZ[1, 0] = targetxyY[1, 0] * targetxyY[1, 2] / targetxyY[1, 1];
        //    targetXYZ[1, 1] = targetxyY[1, 2];
        //    targetXYZ[1, 2] = (1 - targetxyY[1, 0] - targetxyY[1, 1]) * targetxyY[1, 2] / targetxyY[1, 1];

        //    targetXYZ[2, 0] = targetxyY[2, 0] * targetxyY[2, 2] / targetxyY[2, 1];
        //    targetXYZ[2, 1] = targetxyY[2, 2];
        //    targetXYZ[2, 2] = (1 - targetxyY[2, 0] - targetxyY[2, 1]) * targetxyY[2, 2] / targetxyY[2, 1];

        //    DoubleMatrix targetRGB = pRGBInverse * targetXYZ;

        //    DoubleMatrix[,] TMatrix = new DoubleMatrix[partitionRow, partitionColumn];
        //    DoubleMatrix[,] SignalRGB = new DoubleMatrix[partitionRow, partitionColumn];
        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            TMatrix[i, j] = new double[3, 3];

        //            DoubleMatrix originalRGBInverse = ledCollection.OriginalRGB[i, j].Inverse;

        //            DoubleMatrix Columns0 = new double[3, 1];
        //            Columns0[0, 0] = originalRGBInverse[0, 0];
        //            Columns0[0, 1] = originalRGBInverse[0, 1];
        //            Columns0[0, 2] = originalRGBInverse[0, 2];

        //            DoubleMatrix Columns1 = new double[3, 1];
        //            Columns1[0, 0] = originalRGBInverse[1, 0];
        //            Columns1[0, 1] = originalRGBInverse[1, 1];
        //            Columns1[0, 2] = originalRGBInverse[1, 2];

        //            DoubleMatrix Columns2 = new double[3, 1];
        //            Columns2[0, 0] = originalRGBInverse[2, 0];
        //            Columns2[0, 1] = originalRGBInverse[2, 1];
        //            Columns2[0, 2] = originalRGBInverse[2, 2];

        //            TMatrix[i, j].Columns[0] = originalMaximumColor * Columns0;
        //            TMatrix[i, j].Columns[1] = originalMaximumColor * Columns1;
        //            TMatrix[i, j].Columns[2] = originalMaximumColor * Columns2;

        //            SignalRGB[i, j] = new double[3, 3];
        //            SignalRGB[i, j] = TMatrix[i, j] * targetRGB;
        //            ledCollection.KRGB[i, j] = SignalRGB[i, j] * originalMaximumColorInverse;

        //            for (int k = 0; k < 3; k++)
        //            {
        //                for (int l = 0; l < 3; l++)
        //                {
        //                    if (ledCollection.KRGB[i, j][k, l] < 0)
        //                        ledCollection.KRGB[i, j][k, l] = 0;
        //                    else if (ledCollection.KRGB[i, j][k, l] > 1)
        //                        ledCollection.KRGB[i, j][k, l] = 1;
        //                }
        //            }
        //            ledCollection.KRGB[i, j] *= LEDCOLORBIT;
        //        }
        //    }

        //    ledCollection.IsDone = true;
        //}

        //public void CountOffset1(int partitionNum)
        //{
        //    if (partitionColumn == 0 || partitionRow == 0)
        //    {
        //        throw new CorrectiveException("分区的行或列不能为零。");
        //    }

        //    LEDCollection ledCollection = ledCollections[0];

        //    //for (int i = 0; i < resolHeight; i++)
        //    //{
        //    //    for (int j = 0; j < resolWidth; j++)
        //    //    {
        //    //        ledCollection.OriginalRGB[i, j] = new double[3, 3] {{65535,0,0},
        //    //                                                  {0,65535,0},
        //    //                                                  {0,0,65535}};
        //    //        ledCollection.KRGB[i, j] = new double[3, 3] {{65535,0,0},
        //    //                                           {0,65535,0},
        //    //                                           {0,0,65535}};
        //    //    }
        //    //}

        //    #region 数据采集

        //    //Parallel.Invoke(() =>
        //    //{
        //    //    RedPartitionDataAnalysis(partitionNum, ledCollection);
        //    //},
        //    //() =>
        //    //{
        //    //    GreenPartitionDataAnalysis(partitionNum, ledCollection);
        //    //},
        //    //() =>
        //    //{
        //    //    BluePartitionDataAnalysis(partitionNum, ledCollection);
        //    //});

        //    //RedPartitionDataAnalysis(partitionNum, ledCollection);
        //    //GreenPartitionDataAnalysis(partitionNum, ledCollection);
        //    //BluePartitionDataAnalysis(partitionNum, ledCollection);

        //    #endregion

        //    ///////////
        //    //double rr = 0;
        //    //double rg = 0;
        //    //double rb = 0;
        //    //double gr = 0;
        //    //double gg = 0;
        //    //double gb = 0;
        //    //double br = 0;
        //    //double bg = 0;
        //    //double bb = 0;

        //    //int rBad = 0;
        //    //int gBad = 0;
        //    //int bBad = 0;

        //    //for (int i = 0; i < partitionRow; i++)
        //    //{
        //    //    for (int j = 0; j < partitionColumn; j++)
        //    //    {
        //    //        if (ledCollection.OriginalRGB[i, j][0, 0] > 0)
        //    //        {
        //    //            rr += ledCollection.OriginalRGB[i, j][0, 0];
        //    //            rg += ledCollection.OriginalRGB[i, j][0, 1];
        //    //            rb += ledCollection.OriginalRGB[i, j][0, 2];
        //    //        }
        //    //        else
        //    //        {
        //    //            rBad++;
        //    //        }
        //    //        if (ledCollection.OriginalRGB[i, j][1, 1] > 0)
        //    //        {
        //    //            gr += ledCollection.OriginalRGB[i, j][1, 0];
        //    //            gg += ledCollection.OriginalRGB[i, j][1, 1];
        //    //            gb += ledCollection.OriginalRGB[i, j][1, 2];
        //    //        }
        //    //        else
        //    //        {
        //    //            gBad++;
        //    //        }
        //    //        if (ledCollection.OriginalRGB[i, j][2, 2] > 0)
        //    //        {
        //    //            br += ledCollection.OriginalRGB[i, j][2, 0];
        //    //            bg += ledCollection.OriginalRGB[i, j][2, 1];
        //    //            bb += ledCollection.OriginalRGB[i, j][2, 2];
        //    //        }
        //    //        else
        //    //        {
        //    //            bBad++;
        //    //        }
        //    //    }
        //    //}

        //    //rr = rr / (partitionRow * partitionColumn - rBad);
        //    //rg = rg / (partitionRow * partitionColumn - rBad);
        //    //rb = rb / (partitionRow * partitionColumn - rBad);

        //    //gr = gr / (partitionRow * partitionColumn - gBad);
        //    //gg = gg / (partitionRow * partitionColumn - gBad);
        //    //gb = gb / (partitionRow * partitionColumn - gBad);

        //    //br = br / (partitionRow * partitionColumn - bBad);
        //    //bg = bg / (partitionRow * partitionColumn - bBad);
        //    //bb = bb / (partitionRow * partitionColumn - bBad);

        //    //DoubleMatrix pingjun = new double[,]{ { rr, gr, br }, 
        //    //                                      { rg, gg, bg }, 
        //    //                                      { rb, gb, bb }};

        //    //DoubleMatrix pingjunInverse = pingjun.Inverse;

        //    ////DoubleMatrix celiang = new double[,]{ { 2070, 413.5135, 487.5 }, 
        //    ////                                      { 900, 1800, 300 }, 
        //    ////                                      { 30, 218.9189, 2962.5 } };

        //    //DoubleMatrix celiang = new double[,]{ { 299, 56.28378, 65 }, 
        //    //                                      { 130, 245, 40 }, 
        //    //                                      { 4.33, 29.7973, 395 } };

        //    //DoubleMatrix pRGB = celiang * pingjunInverse;

        //    //DoubleMatrix pRGBInverse = pRGB.Inverse;

        //    //DoubleMatrix targetXYZ = new double[3, 3];
        //    //targetXYZ[0, 0] = targetxyY[0, 0] * targetxyY[0, 2] / targetxyY[0, 1];
        //    //targetXYZ[0, 1] = targetxyY[0, 2];
        //    //targetXYZ[0, 2] = (1 - targetxyY[0, 0] - targetxyY[0, 1]) * targetxyY[0, 2] / targetxyY[0, 1];

        //    //targetXYZ[1, 0] = targetxyY[1, 0] * targetxyY[1, 2] / targetxyY[1, 1];
        //    //targetXYZ[1, 1] = targetxyY[1, 2];
        //    //targetXYZ[1, 2] = (1 - targetxyY[1, 0] - targetxyY[1, 1]) * targetxyY[1, 2] / targetxyY[1, 1];

        //    //targetXYZ[2, 0] = targetxyY[2, 0] * targetxyY[2, 2] / targetxyY[2, 1];
        //    //targetXYZ[2, 1] = targetxyY[2, 2];
        //    //targetXYZ[2, 2] = (1 - targetxyY[2, 0] - targetxyY[2, 1]) * targetxyY[2, 2] / targetxyY[2, 1];

        //    //DoubleMatrix targetRGB = pRGBInverse * targetXYZ;

        //    //DoubleMatrix[,] TMatrix = new DoubleMatrix[partitionRow, partitionColumn];
        //    //DoubleMatrix[,] SignalRGB = new DoubleMatrix[partitionRow, partitionColumn];
        //    //for (int i = 0; i < partitionRow; i++)
        //    //{
        //    //    for (int j = 0; j < partitionColumn; j++)
        //    //    {
        //    //        TMatrix[i, j] = new double[3, 3];

        //    //        DoubleMatrix originalRGBInverse = ledCollection.OriginalRGB[i, j].Inverse;

        //    //        DoubleMatrix Columns0 = new double[3, 1];
        //    //        Columns0[0, 0] = originalRGBInverse[0, 0];
        //    //        Columns0[0, 1] = originalRGBInverse[0, 1];
        //    //        Columns0[0, 2] = originalRGBInverse[0, 2];

        //    //        DoubleMatrix Columns1 = new double[3, 1];
        //    //        Columns1[0, 0] = originalRGBInverse[1, 0];
        //    //        Columns1[0, 1] = originalRGBInverse[1, 1];
        //    //        Columns1[0, 2] = originalRGBInverse[1, 2];

        //    //        DoubleMatrix Columns2 = new double[3, 1];
        //    //        Columns2[0, 0] = originalRGBInverse[2, 0];
        //    //        Columns2[0, 1] = originalRGBInverse[2, 1];
        //    //        Columns2[0, 2] = originalRGBInverse[2, 2];

        //    //        TMatrix[i, j].Columns[0] = originalMaximumColor * Columns0;
        //    //        TMatrix[i, j].Columns[1] = originalMaximumColor * Columns1;
        //    //        TMatrix[i, j].Columns[2] = originalMaximumColor * Columns2;

        //    //        SignalRGB[i, j] = new double[3, 3];
        //    //        SignalRGB[i, j] = TMatrix[i, j] * targetRGB;
        //    //        ledCollection.KRGB[i, j] = SignalRGB[i, j] * originalMaximumColorInverse;

        //    //        for (int k = 0; k < 3; k++)
        //    //        {
        //    //            for (int l = 0; l < 3; l++)
        //    //            {
        //    //                if (ledCollection.KRGB[i, j][k, l] < 0)
        //    //                    ledCollection.KRGB[i, j][k, l] = 0;
        //    //                else if (ledCollection.KRGB[i, j][k, l] > 1)
        //    //                    ledCollection.KRGB[i, j][k, l] = 1;
        //    //            }
        //    //        }
        //    //        ledCollection.KRGB[i, j] *= LEDCOLORBIT;
        //    //    }
        //    //}

        //    #region Delete

        //    #region 将RGB三种颜色的RGB像素值转换为XYZ空间值

        //    DoubleMatrix[,] originalXYZ = new DoubleMatrix[partitionRow, partitionColumn];
        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            originalXYZ[i, j] = new double[3, 3];
        //            originalXYZ[i, j].Columns[0] = sRGB * ledCollection.OriginalRGB[i, j].Columns[0];
        //            originalXYZ[i, j].Columns[1] = sRGB * ledCollection.OriginalRGB[i, j].Columns[1];
        //            originalXYZ[i, j].Columns[2] = sRGB * ledCollection.OriginalRGB[i, j].Columns[2];
        //        }
        //    }

        //    #endregion

        //    #region 剔除坏点

        //    List<int> redDeadList = null;
        //    List<int> greenDeadList = null;
        //    List<int> blueDeadList = null;

        //    Parallel.Invoke(() =>
        //    {
        //        redDeadList = CountDeadLed(originalXYZ, Color.Red);
        //    },
        //    () =>
        //    {
        //        greenDeadList = CountDeadLed(originalXYZ, Color.Green);
        //    },
        //    () =>
        //    {
        //        blueDeadList = CountDeadLed(originalXYZ, Color.Blue);
        //    });

        //    List<int> deadList = redDeadList.Concat(greenDeadList).Concat(blueDeadList).Distinct().ToList();

        //    #endregion

        //    #region 求目标三刺激值

        //    //double XrWithoutDead = 0.0;
        //    //double YrWithoutDead = 0.0;
        //    //double ZrWithoutDead = 0.0;
        //    //double XgWithoutDead = 0.0;
        //    //double YgWithoutDead = 0.0;
        //    //double ZgWithoutDead = 0.0;
        //    //double XbWithoutDead = 0.0;
        //    //double YbWithoutDead = 0.0;
        //    //double ZbWithoutDead = 0.0;

        //    //for (int i = 0; i < partitionRow; i++)
        //    //{
        //    //    for (int j = 0; j < partitionColumn; j++)
        //    //    {
        //    //        int num = i * partitionColumn + j;
        //    //        if (deadList.Contains(num))
        //    //        {
        //    //            continue;
        //    //        }
        //    //        XrWithoutDead += originalXYZ[i, j][0, 0];
        //    //        YrWithoutDead += originalXYZ[i, j][1, 0];
        //    //        ZrWithoutDead += originalXYZ[i, j][2, 0];

        //    //        XgWithoutDead += originalXYZ[i, j][0, 1];
        //    //        YgWithoutDead += originalXYZ[i, j][1, 1];
        //    //        ZgWithoutDead += originalXYZ[i, j][2, 1];

        //    //        XbWithoutDead += originalXYZ[i, j][0, 2];
        //    //        YbWithoutDead += originalXYZ[i, j][1, 2];
        //    //        ZbWithoutDead += originalXYZ[i, j][2, 2];
        //    //    }
        //    //}

        //    //int count = partitionRow * partitionColumn - deadList.Count();
        //    //XrWithoutDead = XrWithoutDead / count;
        //    //YrWithoutDead = YrWithoutDead / count;
        //    //ZrWithoutDead = ZrWithoutDead / count;

        //    //XgWithoutDead = XgWithoutDead / count;
        //    //YgWithoutDead = YgWithoutDead / count;
        //    //ZgWithoutDead = ZgWithoutDead / count;

        //    //XbWithoutDead = XbWithoutDead / count;
        //    //YbWithoutDead = YbWithoutDead / count;
        //    //ZbWithoutDead = ZbWithoutDead / count;

        //    //DoubleMatrix[,] targetXYZ = GetTargetXYZ(originalXYZ, deadList, XrWithoutDead, YrWithoutDead, ZrWithoutDead, XgWithoutDead, YgWithoutDead, ZgWithoutDead, XbWithoutDead, YbWithoutDead, ZbWithoutDead, 1.0);

        //    #endregion

        //    /////////
        //    //DoubleMatrix targetXYZ1 = new double[,] { { 418.75, 141.2857143, 100.9411765 }, 
        //    //                                          { 200, 430, 60 }, 
        //    //                                          { 6.25, 43, 544.9411765 } };
        //    //DoubleMatrix[,] targetXYZ = originalXYZ;

        //    //for (int i = 0; i < resolHeight; i++)
        //    //{
        //    //    for (int j = 0; j < resolWidth; j++)
        //    //    {
        //    //        for (int m = 0; m < 3; m++)
        //    //        {
        //    //            for (int n = 0; n < 3; n++)
        //    //            {
        //    //                if (targetXYZ[i, j][m, n] >= targetXYZ1[m, n])
        //    //                {
        //    //                    targetXYZ[i, j][m, n] = targetXYZ1[m, n];
        //    //                }
        //    //            }
        //    //        }
        //    //    }
        //    //}

        //    //DoubleMatrix targetXYZ = new double[,] { {1845.22, 415.8591549, 455.625 }, 
        //    //                                            { 824, 1554,297 }, 
        //    //                                            { 32.41967, 218.8732, 2622.375 } };

        //    DoubleMatrix targetXYZ = new double[,] { { 65535, 65535, 65535 }, 
        //                                                { 65535, 65535, 65535 }, 
        //                                                { 65535, 65535, 65535 } };

        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            int num = i * resolWidth + j;
        //            if (deadList.Contains(num))
        //            {
        //                continue;
        //            }

        //            double aa1 = targetXYZ[0, 0];
        //            double aa2 = originalXYZ[i, j][0, 0];

        //            if (originalXYZ[i, j][0, 0] < targetXYZ[0, 0])
        //            {
        //                targetXYZ[0, 0] = originalXYZ[i, j][0, 0];
        //            }

        //            if (originalXYZ[i, j][1, 0] < targetXYZ[1, 0])
        //            {
        //                targetXYZ[1, 0] = originalXYZ[i, j][1, 0];
        //            }

        //            if (originalXYZ[i, j][2, 0] < targetXYZ[2, 0])
        //            {
        //                targetXYZ[2, 0] = originalXYZ[i, j][2, 0];
        //            }

        //            if (originalXYZ[i, j][0, 1] < targetXYZ[0, 1])
        //            {
        //                targetXYZ[0, 1] = originalXYZ[i, j][0, 1];
        //            }

        //            if (originalXYZ[i, j][1, 1] < targetXYZ[1, 1])
        //            {
        //                targetXYZ[1, 1] = originalXYZ[i, j][1, 1];
        //            }

        //            if (originalXYZ[i, j][2, 1] < targetXYZ[2, 1])
        //            {
        //                targetXYZ[2, 1] = originalXYZ[i, j][2, 1];
        //            }

        //            if (originalXYZ[i, j][0, 2] < targetXYZ[0, 2])
        //            {
        //                targetXYZ[0, 2] = originalXYZ[i, j][0, 2];
        //            }

        //            if (originalXYZ[i, j][1, 2] < targetXYZ[1, 2])
        //            {
        //                targetXYZ[1, 2] = originalXYZ[i, j][1, 2];
        //            }

        //            if (originalXYZ[i, j][2, 2] < targetXYZ[2, 2])
        //            {
        //                targetXYZ[2, 2] = originalXYZ[i, j][2, 2];
        //            }
        //        }
        //    }

        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            int num = i * resolWidth + j;
        //            if (deadList.Contains(num))
        //            {
        //                continue;
        //            }

        //            if (originalXYZ[i, j][0, 0] >= targetXYZ[0, 0])
        //            {
        //                originalXYZ[i, j][0, 0] = targetXYZ[0, 0];
        //            }

        //            if (originalXYZ[i, j][1, 0] >= targetXYZ[1, 0])
        //            {
        //                originalXYZ[i, j][1, 0] = targetXYZ[1, 0];
        //            }

        //            if (originalXYZ[i, j][2, 0] >= targetXYZ[2, 0])
        //            {
        //                originalXYZ[i, j][2, 0] = targetXYZ[2, 0];
        //            }

        //            if (originalXYZ[i, j][0, 1] >= targetXYZ[0, 1])
        //            {
        //                originalXYZ[i, j][0, 1] = targetXYZ[0, 1];
        //            }

        //            if (originalXYZ[i, j][1, 1] >= targetXYZ[1, 1])
        //            {
        //                originalXYZ[i, j][1, 1] = targetXYZ[1, 1];
        //            }

        //            if (originalXYZ[i, j][2, 1] >= targetXYZ[2, 1])
        //            {
        //                originalXYZ[i, j][2, 1] = targetXYZ[2, 1];
        //            }

        //            if (originalXYZ[i, j][0, 2] >= targetXYZ[0, 2])
        //            {
        //                originalXYZ[i, j][0, 2] = targetXYZ[0, 2];
        //            }

        //            if (originalXYZ[i, j][1, 2] >= targetXYZ[1, 2])
        //            {
        //                originalXYZ[i, j][1, 2] = targetXYZ[1, 2];
        //            }

        //            if (originalXYZ[i, j][2, 2] >= targetXYZ[2, 2])
        //            {
        //                originalXYZ[i, j][2, 2] = targetXYZ[2, 2];
        //            }
        //        }
        //    }


        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            DoubleMatrix originalRGBInverse = ledCollection.OriginalRGB[i, j].Inverse;
        //            DoubleMatrix T = originalMaximumColor * originalRGBInverse;
        //            DoubleMatrix TsRGBInverse = T * sRGBInverse;

        //            ledCollection.KRGB[i, j].Columns[0] = TsRGBInverse * originalXYZ[i, j].Columns[0];
        //            ledCollection.KRGB[i, j].Columns[1] = TsRGBInverse * originalXYZ[i, j].Columns[1];
        //            ledCollection.KRGB[i, j].Columns[2] = TsRGBInverse * originalXYZ[i, j].Columns[2];

        //            for (int k = 0; k < 3; k++)
        //            {
        //                for (int l = 0; l < 3; l++)
        //                {
        //                    if (ledCollection.KRGB[i, j][k, l] < 0)
        //                    {
        //                        ledCollection.KRGB[i, j][k, l] = 0;
        //                    }

        //                    if (ledCollection.KRGB[i, j][k, l] > 255)
        //                    {
        //                        ledCollection.KRGB[i, j][k, l] = 255;
        //                    }
        //                }
        //            }

        //            ledCollection.KRGB[i, j] = ledCollection.KRGB[i, j] * originalMaximumColorInverse;

        //            for (int k = 0; k < 3; k++)
        //            {
        //                for (int l = 0; l < 3; l++)
        //                {
        //                    if (ledCollection.KRGB[i, j][k, l] > 1)
        //                    {
        //                        ledCollection.KRGB[i, j][k, l] = 1;
        //                    }
        //                }
        //            }

        //            ledCollection.KRGB[i, j] = ledCollection.KRGB[i, j] * LEDCOLORBIT;
        //        }
        //    }

        //    #region 求补偿系数

        //    //for (int i = 0; i < partitionRow; i++)
        //    //{
        //    //    for (int j = 0; j < partitionColumn; j++)
        //    //    {
        //    //        DoubleMatrix originalRGBInverse = ledCollection.OriginalRGB[i, j].Inverse;
        //    //        DoubleMatrix T = originalMaximumColor * originalRGBInverse;
        //    //        DoubleMatrix TsRGBInverse = T * sRGBInverse;

        //    //        ledCollection.KRGB[i, j].Columns[0] = TsRGBInverse * targetXYZ[i, j].Columns[0];
        //    //        ledCollection.KRGB[i, j].Columns[1] = TsRGBInverse * targetXYZ[i, j].Columns[1];
        //    //        ledCollection.KRGB[i, j].Columns[2] = TsRGBInverse * targetXYZ[i, j].Columns[2];

        //    //        ///////
        //    //        //ledCollection.KRGB[i, j].Columns[0] = TsRGBInverse * targetXYZ1.Columns[0];
        //    //        //ledCollection.KRGB[i, j].Columns[1] = TsRGBInverse * targetXYZ1.Columns[1];
        //    //        //ledCollection.KRGB[i, j].Columns[2] = TsRGBInverse * targetXYZ1.Columns[2];

        //    //        for (int k = 0; k < 3; k++)
        //    //        {
        //    //            for (int l = 0; l < 3; l++)
        //    //            {
        //    //                if (ledCollection.KRGB[i, j][k, l] < 0)
        //    //                {
        //    //                    ledCollection.KRGB[i, j][k, l] = 0;
        //    //                }

        //    //                if (ledCollection.KRGB[i, j][k, l] > 255)
        //    //                {
        //    //                    ledCollection.KRGB[i, j][k, l] = 255;
        //    //                }
        //    //            }
        //    //        }

        //    //        ledCollection.KRGB[i, j] = ledCollection.KRGB[i, j] * TInverse;

        //    //        for (int k = 0; k < 3; k++)
        //    //        {
        //    //            for (int l = 0; l < 3; l++)
        //    //            {
        //    //                if (ledCollection.KRGB[i, j][k, l] > 1)
        //    //                {
        //    //                    ledCollection.KRGB[i, j][k, l] = 1;
        //    //                }
        //    //            }
        //    //        }

        //    //        ledCollection.KRGB[i, j] = ledCollection.KRGB[i, j] * LEDCOLORBIT;
        //    //    }
        //    //}

        //    #endregion

        //    #endregion

        //    ledCollection.IsDone = true;
        //}

        /// <summary>
        /// 从采集数据中计算全屏校正补偿系数
        /// </summary>
        /// <param name="column">分屏所在列数</param>
        /// <param name="row">分屏所在行数</param>
        /// <param name="splitScreenNum">分屏号码</param>
        public void FullCountOffset(int splitScreenNum)
        {
            if (splitScreenColumn == 0 || splitScreenRow == 0)
            {
                throw new CorrectiveException("分屏的行或列不能为零。");
            }

            LEDCollection ledCollection = splitScreenLedCollections[splitScreenNum - 1];
            DoubleMatrix[,] originalRGB = new DoubleMatrix[SeparateRow, SeparateColumn];
            DoubleMatrix[,] originalXYZ = new DoubleMatrix[SeparateRow, SeparateColumn];

            for (int k = 0; k < PartitionCount; k++)
            {
                double rr = 0;
                double rg = 0;
                double rb = 0;
                double gr = 0;
                double gg = 0;
                double gb = 0;
                double br = 0;
                double bg = 0;
                double bb = 0;

                int rBad = 0;
                int gBad = 0;
                int bBad = 0;

                int separateRow = k / SeparateColumn;
                int separateColumn = k % SeparateColumn;

                for (int i = 0; i < partitionRow; i++)
                {
                    for (int j = 0; j < partitionColumn; j++)
                    {
                        int row = separateRow * partitionRow + i;
                        int column = separateColumn * partitionColumn + j;

                        if (ledCollection.OriginalRGB[row, column][0, 0] > 0)
                        {
                            rr += ledCollection.OriginalRGB[row, column][0, 0];
                            rg += ledCollection.OriginalRGB[row, column][0, 1];
                            rb += ledCollection.OriginalRGB[row, column][0, 2];
                        }
                        else
                        {
                            rBad++;
                        }

                        if (ledCollection.OriginalRGB[row, column][1, 1] > 0)
                        {
                            gr += ledCollection.OriginalRGB[row, column][1, 0];
                            gg += ledCollection.OriginalRGB[row, column][1, 1];
                            gb += ledCollection.OriginalRGB[row, column][1, 2];
                        }
                        else
                        {
                            gBad++;
                        }

                        if (ledCollection.OriginalRGB[row, column][2, 2] > 0)
                        {
                            br += ledCollection.OriginalRGB[row, column][2, 0];
                            bg += ledCollection.OriginalRGB[row, column][2, 1];
                            bb += ledCollection.OriginalRGB[row, column][2, 2];
                        }
                        else
                        {
                            bBad++;
                        }
                    }
                }

                rr = rr / (partitionRow * partitionColumn - rBad);
                rg = rg / (partitionRow * partitionColumn - rBad);
                rb = rb / (partitionRow * partitionColumn - rBad);

                gr = gr / (partitionRow * partitionColumn - gBad);
                gg = gg / (partitionRow * partitionColumn - gBad);
                gb = gb / (partitionRow * partitionColumn - gBad);

                br = br / (partitionRow * partitionColumn - bBad);
                bg = bg / (partitionRow * partitionColumn - bBad);
                bb = bb / (partitionRow * partitionColumn - bBad);

                DoubleMatrix pingjun = new double[,]{ { rr, gr, br }, 
                                                  { rg, gg, bg }, 
                                                  { rb, gb, bb }};

                originalRGB[separateRow, separateColumn] = pingjun;

                DoubleMatrix pingjunInverse = pingjun.Inverse;

                DoubleMatrix celiang = new double[,]{ { 299, 56.28378, 65 }, 
                                                  { 130, 245, 40 }, 
                                                  { 4.33, 29.7973, 395 } };

                if (pRGB.IsEmpty)
                {
                    pRGB = celiang * pingjunInverse;
                    pRGBInverse = pRGB.Inverse;
                }

                originalXYZ[separateRow, separateColumn] = new double[3, 3];
                originalXYZ[separateRow, separateColumn].Columns[0] = pRGB * pingjun.Columns[0];
                originalXYZ[separateRow, separateColumn].Columns[1] = pRGB * pingjun.Columns[1];
                originalXYZ[separateRow, separateColumn].Columns[2] = pRGB * pingjun.Columns[2];
            }

            DoubleMatrix targetXYZ = new double[3, 3]{{65535,65535,65535},
                                                      {65535,65535,65535},
                                                      {65535,65535,65535}};

            for (int i = 0; i < SeparateRow; i++)
            {
                for (int j = 0; j < SeparateColumn; j++)
                {
                    if (targetXYZ[0, 0] > originalXYZ[i, j][0, 0])
                    {
                        targetXYZ[0, 0] = originalXYZ[i, j][0, 0];
                    }
                    if (targetXYZ[1, 0] > originalXYZ[i, j][1, 0])
                    {
                        targetXYZ[1, 0] = originalXYZ[i, j][1, 0];
                    }
                    if (targetXYZ[2, 0] > originalXYZ[i, j][2, 0])
                    {
                        targetXYZ[2, 0] = originalXYZ[i, j][2, 0];
                    }

                    if (targetXYZ[0, 1] > originalXYZ[i, j][0, 1])
                    {
                        targetXYZ[0, 1] = originalXYZ[i, j][0, 1];
                    }
                    if (targetXYZ[1, 1] > originalXYZ[i, j][1, 1])
                    {
                        targetXYZ[1, 1] = originalXYZ[i, j][1, 1];
                    }
                    if (targetXYZ[2, 1] > originalXYZ[i, j][2, 1])
                    {
                        targetXYZ[2, 1] = originalXYZ[i, j][2, 1];
                    }

                    if (targetXYZ[0, 2] > originalXYZ[i, j][0, 2])
                    {
                        targetXYZ[0, 2] = originalXYZ[i, j][0, 2];
                    }
                    if (targetXYZ[1, 2] > originalXYZ[i, j][1, 2])
                    {
                        targetXYZ[1, 2] = originalXYZ[i, j][1, 2];
                    }
                    if (targetXYZ[2, 2] > originalXYZ[i, j][2, 2])
                    {
                        targetXYZ[2, 2] = originalXYZ[i, j][2, 2];
                    }
                }
            }

            DoubleMatrix targetRGB = pRGBInverse * targetXYZ;
            DoubleMatrix[,] TMatrix = new DoubleMatrix[SeparateRow, SeparateColumn];
            DoubleMatrix[,] SignalRGB = new DoubleMatrix[SeparateRow, SeparateColumn];
            DoubleMatrix[,] KRGB = new DoubleMatrix[SeparateRow, SeparateColumn];

            for (int i = 0; i < SeparateRow; i++)
            {
                for (int j = 0; j < SeparateColumn; j++)
                {
                    TMatrix[i, j] = new double[3, 3];

                    DoubleMatrix originalRGBInverse = originalRGB[i, j].Inverse;

                    DoubleMatrix Columns0 = new double[3, 1];
                    Columns0[0, 0] = originalRGBInverse[0, 0];
                    Columns0[0, 1] = originalRGBInverse[0, 1];
                    Columns0[0, 2] = originalRGBInverse[0, 2];

                    DoubleMatrix Columns1 = new double[3, 1];
                    Columns1[0, 0] = originalRGBInverse[1, 0];
                    Columns1[0, 1] = originalRGBInverse[1, 1];
                    Columns1[0, 2] = originalRGBInverse[1, 2];

                    DoubleMatrix Columns2 = new double[3, 1];
                    Columns2[0, 0] = originalRGBInverse[2, 0];
                    Columns2[0, 1] = originalRGBInverse[2, 1];
                    Columns2[0, 2] = originalRGBInverse[2, 2];

                    TMatrix[i, j].Columns[0] = originalMaximumColor * Columns0;
                    TMatrix[i, j].Columns[1] = originalMaximumColor * Columns1;
                    TMatrix[i, j].Columns[2] = originalMaximumColor * Columns2;

                    SignalRGB[i, j] = new double[3, 3];
                    SignalRGB[i, j] = TMatrix[i, j] * targetRGB;
                    KRGB[i, j] = SignalRGB[i, j] * originalMaximumColorInverse;

                    for (int k = 0; k < 3; k++)
                    {
                        for (int l = 0; l < 3; l++)
                        {
                            if (KRGB[i, j][k, l] < 0)
                                KRGB[i, j][k, l] = 0;
                            else if (KRGB[i, j][k, l] > 1)
                                KRGB[i, j][k, l] = 1;
                        }
                    }
                }
            }

            for (int k = 0; k < ledCollections.Count(); k++)
            {
                LEDCollection ledC = ledCollections[k];
                LEDCollection ssledC = splitScreenLedCollections[0];
                int row = k / SeparateColumn;
                int column = k % SeparateColumn;

                for (int i = 0; i < partitionRow; i++)
                {
                    for (int j = 0; j < partitionColumn; j++)
                    {
                        ssledC.KRGB[row * partitionRow + i, column * partitionColumn + j] = ledC.KRGB[i, j] * KRGB[row, column];
                    }
                }
            }

            ledCollection.IsDone = true;
        }

        public void SetAdjustDots(bool isEnable)
        {
            SCP_STATUS_T status3 = SetAdjustDots(Scp_wall.modpg[0].senderId, isEnable);

            if (status3.status != 0)
            {
                throw new Exception("不可能");
            }
        }

        public bool GetAdjustDots()
        {
            SCP_ADJUSTDOTS_T adjustDots = GetAdjustDots(Scp_wall.modpg[0].senderId);

            return adjustDots.enable == 1;
        }

        private int thresholdValue = 30;
        private float radiusSize = 0F;
        private float bad = 0.9F;

        private float LEDSpacing = 0F;
        private float LEDSpacingMax = 0F;
        private float LEDSpacingMin = 0F;
        private float LEDSpacingPercentage = 0.5F;

        public bool isSetRadiusSize = false;

        public List<GroupPixes> badLED = new List<GroupPixes>();
        public int PartitionDataAnalysis(int partitionNum, LEDCollection ledCollection, Color color)
        {
            badLED.Clear();
            if (!isSetRadiusSize)
            {
                radiusSize = 0F;
            }
            string directoryPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Vtron\\LEDCorrective";
            string sourceImageFileName = String.Format("{0}\\{1}_{2}_{3}_{4}.tiff", directoryPath, id, partitionNum, blockNum, color.Name);

            System.Drawing.Image imgInFile = System.Drawing.Image.FromFile(sourceImageFileName);
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imgInFile);
            imgInFile.Dispose();

            Image<Bgr, Byte> imageSource = new Image<Bgr, byte>(sourceImageFileName); //获取源图像
            Image<Gray, Byte> imageGray = imageSource.Convert<Gray, Byte>(); //将源图像转换成灰度图像
            Image<Gray, Byte> imageThreshold = imageGray.ThresholdBinary(new Gray(thresholdValue), new Gray(255d)); //对灰度图像二值化
            Contour<System.Drawing.Point> contour = imageThreshold.FindContours();

            List<GroupPixes> list = new List<GroupPixes>();

            for (var c = contour; c != null; c = c.HNext)
            {
                if (c.Total >= 3 && c.Total < 30)
                {
                    System.Drawing.PointF center;
                    float radius;
                    CvInvoke.cvMinEnclosingCircle(c.Ptr, out center, out radius);

                    GroupPixes groupPixes = new GroupPixes();
                    groupPixes.CenterX = center.X;
                    groupPixes.CenterY = center.Y;
                    groupPixes.radius = radius;

                    list.Add(groupPixes);

                    if (!isSetRadiusSize)
                    {
                        radiusSize += radius;
                    }
                }
            }

            if (!isSetRadiusSize)
            {
                radiusSize = radiusSize / list.Count();
            }

            int blockColumnNum = (blockNum - 1) % blockColumn;
            int blockRowNum = (blockNum - 1) / blockRow;

            int partitionBlockRow = partitionRow / blockRow + ((partitionRow % blockRow) > blockRowNum ? 1 : 0);
            int partitionBlockColumn = partitionColumn / blockColumn + ((partitionColumn % blockColumn) > blockColumnNum ? 1 : 0);

            list = list.Where(gp => gp.radius >= radiusSize * 0.5).ToList();

            if (list.Count() > partitionBlockRow * partitionBlockColumn)
            {
                bitmap.Dispose();
                imageSource.Dispose();
                throw new Exception(String.Format("拟合出{0}个圆，比分区的LED总数（{1}）大", list.Count(), partitionBlockRow * partitionBlockColumn));
            }

            if (list.Count() < partitionBlockRow * partitionBlockColumn * bad)
            {
                bitmap.Dispose();
                imageSource.Dispose();
                throw new Exception(String.Format("拟合出{0}个圆，比分区的LED总数（{1}）小于{2}%", list.Count(), partitionBlockRow * partitionBlockColumn, bad * 100));
            }

            foreach (GroupPixes groupPixes in list)
            {
                int squareLeftTopX = (int)(groupPixes.CenterX + 0.5) - (int)(radiusSize + 0.5) + 1;
                int squareLeftTopY = (int)(groupPixes.CenterY + 0.5) - (int)(radiusSize + 0.5) + 1;
                int squareRightDownX = squareLeftTopX + (((int)(radiusSize + 0.5)) - 1) * 2;
                int squareRightDowY = squareLeftTopY + (((int)(radiusSize + 0.5)) - 1) * 2;

                if (squareLeftTopX < 0 || squareLeftTopY < 0)
                {
                    bitmap.Dispose();
                    imageSource.Dispose();
                    throw new CorrectiveException("拟制圆形出错：squareLeftTopX或squareLeftTopY不能小于零。");
                }
                for (int m = squareLeftTopX; m <= squareRightDownX; m++)
                {
                    for (int n = squareLeftTopY; n <= squareRightDowY; n++)
                    {
                        Pixe pixe = new Pixe();
                        System.Drawing.Color bitmapColor = bitmap.GetPixel(m, n);
                        pixe.X = m;
                        pixe.Y = n;
                        pixe.R = bitmapColor.R;
                        pixe.G = bitmapColor.G;
                        pixe.B = bitmapColor.B;
                        groupPixes.list.Add(pixe);
                    }
                }
            }

            bitmap.Dispose();
            imageSource.Dispose();

            GroupPixes[,] arrGroupPixes = new GroupPixes[partitionBlockRow, partitionBlockColumn];
            List<GroupPixes> listOrderByXY = list.OrderBy(ll => ll.CenterX + ll.CenterY).ToList();

            if (!isSetRadiusSize)
            {
                LEDSpacing = (float)Math.Sqrt((listOrderByXY[0].CenterX - listOrderByXY[1].CenterX) * (listOrderByXY[0].CenterX - listOrderByXY[1].CenterX) + (listOrderByXY[0].CenterY - listOrderByXY[1].CenterY) * (listOrderByXY[0].CenterY - listOrderByXY[1].CenterY));
                LEDSpacingMax = LEDSpacing * (1 + LEDSpacingPercentage);
                LEDSpacingMin = LEDSpacing * LEDSpacingPercentage;
            }

            GroupPixes leftTopGroupPixes = listOrderByXY[0];

            arrGroupPixes[0, 0] = leftTopGroupPixes;
            LEDDataAnalysis(ledCollection, leftTopGroupPixes, blockRowNum, blockColumnNum, color);
            listOrderByXY.Remove(leftTopGroupPixes);
            GroupPixes currentGroupPixes = leftTopGroupPixes;

            for (int row = 0; row < partitionBlockRow; row++)
            {
                for (int column = 1; column < partitionBlockColumn; column++)
                {
                    GroupPixes[] rightNearbyCurrentGroupPixes = listOrderByXY.Where(v => v.CenterX - currentGroupPixes.CenterX > LEDSpacingMin &&
                                 v.CenterX - currentGroupPixes.CenterX < LEDSpacingMax &&
                                 Math.Abs(v.CenterY - currentGroupPixes.CenterY) < LEDSpacingMin).OrderBy(v => v.CenterY).ToArray();

                    if (rightNearbyCurrentGroupPixes.Count() < 1)
                    {
                        GroupPixes a = new GroupPixes();
                        a.Row = row;
                        a.Column = column;
                        a.CenterX = currentGroupPixes.CenterX + LEDSpacing;
                        a.CenterY = currentGroupPixes.CenterY;
                        a.radius = radiusSize;
                        a.list = new List<Pixe>();
                        Pixe b1 = new Pixe();
                        b1.R = 255;
                        b1.G = 255;
                        b1.B = 255;
                        a.list.Add(b1);
                        rightNearbyCurrentGroupPixes = new GroupPixes[] { a };

                        badLED.Add(a);
                    }
                    GroupPixes rightOne = rightNearbyCurrentGroupPixes[0];

                    arrGroupPixes[row, column] = rightOne;
                    LEDDataAnalysis(ledCollection, rightOne, row * blockRow + blockRowNum, column * BlockColumn + blockColumnNum, color);
                    listOrderByXY.Remove(rightOne);
                    currentGroupPixes = rightOne;

                    if (column == partitionBlockColumn - 1)
                    {
                        if (row != partitionBlockRow - 1)
                        {
                            GroupPixes currentRowfirstGroupPixes = arrGroupPixes[row, 0];
                            GroupPixes[] rightNearbyCurrentRowFirstGroupPixes = listOrderByXY.Where(v => Math.Abs(v.CenterX - currentRowfirstGroupPixes.CenterX) < LEDSpacingMin &&
                                                                                                             v.CenterY - currentRowfirstGroupPixes.CenterY > LEDSpacingMin &&
                                                                                                             v.CenterY - currentRowfirstGroupPixes.CenterY < LEDSpacingMax).ToArray();
                            if (rightNearbyCurrentRowFirstGroupPixes.Count() != 1)
                            {
                                GroupPixes a = new GroupPixes();
                                a.Row = row;
                                a.Column = column;
                                a.CenterX = currentRowfirstGroupPixes.CenterX;
                                a.CenterY = currentRowfirstGroupPixes.CenterY + LEDSpacing;
                                a.radius = radiusSize;
                                a.list = new List<Pixe>();
                                Pixe b1 = new Pixe();
                                b1.R = 255;
                                b1.G = 255;
                                b1.B = 255;
                                a.list.Add(b1);
                                rightNearbyCurrentRowFirstGroupPixes = new GroupPixes[] { a };

                                badLED.Add(a);
                            }
                            GroupPixes downOne = rightNearbyCurrentRowFirstGroupPixes[0];

                            arrGroupPixes[row + 1, 0] = downOne;
                            LEDDataAnalysis(ledCollection, downOne, (row + 1) * blockRow + blockRowNum, blockColumnNum, color);
                            listOrderByXY.Remove(downOne);
                            currentGroupPixes = downOne;
                        }
                    }
                }
            }

            if (listOrderByXY.Count() != 0)
            {
                throw new Exception("数据采集不正确，采集到的LED点信息对应不上实际LED点位置。");
            }

            isSetRadiusSize = true;

            return list.Count();
        }

        public int SplitScreenDataAnalysis(int partitionNum, LEDCollection ledCollection, Color color)
        {
            badLED.Clear();
            if (!isSetRadiusSize)
            {
                radiusSize = 0F;
            }
            string directoryPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Vtron\\LEDCorrective";
            string sourceImageFileName = String.Format("{0}\\{1}_{2}_Full{3}.tiff", directoryPath, id, partitionNum, color.Name);

            System.Drawing.Image imgInFile = System.Drawing.Image.FromFile(sourceImageFileName);
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imgInFile);
            imgInFile.Dispose();

            Image<Bgr, Byte> imageSource = new Image<Bgr, byte>(sourceImageFileName); //获取源图像
            Image<Gray, Byte> imageGray = imageSource.Convert<Gray, Byte>(); //将源图像转换成灰度图像
            Image<Gray, Byte> imageThreshold = imageGray.ThresholdBinary(new Gray(thresholdValue), new Gray(255d)); //对灰度图像二值化
            Contour<System.Drawing.Point> contour = imageThreshold.FindContours();

            List<GroupPixes> list = new List<GroupPixes>();

            for (var c = contour; c != null; c = c.HNext)
            {
                if (c.Total >= 3 && c.Total < 30)
                {
                    System.Drawing.PointF center;
                    float radius;
                    CvInvoke.cvMinEnclosingCircle(c.Ptr, out center, out radius);

                    GroupPixes groupPixes = new GroupPixes();
                    groupPixes.CenterX = center.X;
                    groupPixes.CenterY = center.Y;
                    groupPixes.radius = radius;

                    list.Add(groupPixes);

                    if (!isSetRadiusSize)
                    {
                        radiusSize += radius;
                    }
                }
            }

            if (!isSetRadiusSize)
            {
                radiusSize = radiusSize / list.Count();
            }

            if (list.Count() > splitScreenRow * splitScreenColumn)
            {
                list = list.Where(gp => gp.radius >= radiusSize * 0.5).ToList();
                if (list.Count() > splitScreenRow * splitScreenColumn)
                {
                    bitmap.Dispose();
                    imageSource.Dispose();
                    throw new Exception(String.Format("拟合出{0}个圆，比分区的LED总数（{1}）大", list.Count(), splitScreenRow * splitScreenColumn));
                }
            }

            if (list.Count() < splitScreenRow * splitScreenColumn * bad)
            {
                bitmap.Dispose();
                imageSource.Dispose();
                throw new Exception(String.Format("拟合出{0}个圆，比分区的LED总数（{1}）小于{2}%", list.Count(), splitScreenRow * splitScreenColumn, bad * 100));
            }

            foreach (GroupPixes groupPixes in list)
            {
                int squareLeftTopX = (int)(groupPixes.CenterX + 0.5) - (int)(groupPixes.radius + 0.5) + 1;
                int squareLeftTopY = (int)(groupPixes.CenterY + 0.5) - (int)(groupPixes.radius + 0.5) + 1;
                int squareRightDownX = squareLeftTopX + (((int)(groupPixes.radius + 0.5)) - 1) * 2;
                int squareRightDowY = squareLeftTopY + (((int)(groupPixes.radius + 0.5)) - 1) * 2;

                if (squareLeftTopX < 0 || squareLeftTopY < 0)
                {
                    bitmap.Dispose();
                    imageSource.Dispose();
                    throw new CorrectiveException("拟制圆形出错：squareLeftTopX或squareLeftTopY不能小于零。");
                }
                for (int m = squareLeftTopX; m <= squareRightDownX; m++)
                {
                    for (int n = squareLeftTopY; n <= squareRightDowY; n++)
                    {
                        Pixe pixe = new Pixe();
                        System.Drawing.Color bitmapColor = bitmap.GetPixel(m, n);
                        pixe.X = m;
                        pixe.Y = n;
                        pixe.R = bitmapColor.R;
                        pixe.G = bitmapColor.G;
                        pixe.B = bitmapColor.B;
                        groupPixes.list.Add(pixe);
                    }
                }
            }

            bitmap.Dispose();
            imageSource.Dispose();

            GroupPixes[,] arrGroupPixes = new GroupPixes[splitScreenRow, splitScreenColumn];
            List<GroupPixes> listOrderByXY = list.OrderBy(ll => ll.CenterX + ll.CenterY).ToList();

            if (!isSetRadiusSize)
            {
                LEDSpacing = (float)Math.Sqrt((listOrderByXY[0].CenterX - listOrderByXY[1].CenterX) * (listOrderByXY[0].CenterX - listOrderByXY[1].CenterX) + (listOrderByXY[0].CenterY - listOrderByXY[1].CenterY) * (listOrderByXY[0].CenterY - listOrderByXY[1].CenterY));
                LEDSpacingMax = LEDSpacing * (1 + LEDSpacingPercentage);
                LEDSpacingMin = LEDSpacing * LEDSpacingPercentage;
            }

            GroupPixes leftTopGroupPixes = listOrderByXY[0];

            arrGroupPixes[0, 0] = leftTopGroupPixes;
            LEDDataAnalysis(ledCollection, leftTopGroupPixes, 0, 0, color);
            listOrderByXY.Remove(leftTopGroupPixes);
            GroupPixes currentGroupPixes = leftTopGroupPixes;

            for (int row = 0; row < splitScreenRow; row++)
            {
                for (int column = 1; column < splitScreenColumn; column++)
                {
                    GroupPixes[] rightNearbyCurrentGroupPixes = listOrderByXY.Where(v => v.CenterX - currentGroupPixes.CenterX > LEDSpacingMin &&
                                 v.CenterX - currentGroupPixes.CenterX < LEDSpacingMax &&
                                 Math.Abs(v.CenterY - currentGroupPixes.CenterY) < LEDSpacingMin).OrderBy(v => v.CenterY).ToArray();

                    if (rightNearbyCurrentGroupPixes.Count() < 1)
                    {
                        GroupPixes a = new GroupPixes();
                        a.Row = row;
                        a.Column = column;
                        a.CenterX = currentGroupPixes.CenterX + LEDSpacing;
                        a.CenterY = currentGroupPixes.CenterY;
                        a.radius = radiusSize;
                        a.list = new List<Pixe>();
                        Pixe b1 = new Pixe();
                        b1.R = 255;
                        b1.G = 255;
                        b1.B = 255;
                        a.list.Add(b1);
                        rightNearbyCurrentGroupPixes = new GroupPixes[] { a };

                        badLED.Add(a);
                    }
                    GroupPixes rightOne = rightNearbyCurrentGroupPixes[0];

                    arrGroupPixes[row, column] = rightOne;
                    LEDDataAnalysis(ledCollection, rightOne, row, column, color);
                    listOrderByXY.Remove(rightOne);
                    currentGroupPixes = rightOne;

                    if (column == splitScreenColumn - 1)
                    {
                        if (row != splitScreenRow - 1)
                        {
                            GroupPixes currentRowfirstGroupPixes = arrGroupPixes[row, 0];
                            GroupPixes[] rightNearbyCurrentRowFirstGroupPixes = listOrderByXY.Where(v => Math.Abs(v.CenterX - currentRowfirstGroupPixes.CenterX) < LEDSpacingMin &&
                                                                                                             v.CenterY - currentRowfirstGroupPixes.CenterY > LEDSpacingMin &&
                                                                                                             v.CenterY - currentRowfirstGroupPixes.CenterY < LEDSpacingMax).ToArray();
                            if (rightNearbyCurrentRowFirstGroupPixes.Count() != 1)
                            {
                                GroupPixes a = new GroupPixes();
                                a.Row = row;
                                a.Column = column;
                                a.CenterX = currentRowfirstGroupPixes.CenterX;
                                a.CenterY = currentRowfirstGroupPixes.CenterY + LEDSpacing;
                                a.radius = radiusSize;
                                a.list = new List<Pixe>();
                                Pixe b1 = new Pixe();
                                b1.R = 255;
                                b1.G = 255;
                                b1.B = 255;
                                a.list.Add(b1);
                                rightNearbyCurrentRowFirstGroupPixes = new GroupPixes[] { a };

                                badLED.Add(a);
                            }
                            GroupPixes downOne = rightNearbyCurrentRowFirstGroupPixes[0];

                            arrGroupPixes[row + 1, 0] = downOne;
                            LEDDataAnalysis(ledCollection, downOne, row + 1, 0, color);
                            listOrderByXY.Remove(downOne);
                            currentGroupPixes = downOne;
                        }
                    }
                }
            }

            if (listOrderByXY.Count() != 0)
            {
                throw new Exception("数据采集不正确，采集到的LED点信息对应不上实际LED点位置。");
            }

            isSetRadiusSize = true;
            return list.Count();
        }

        private void LEDDataAnalysis(LEDCollection ledCollection, GroupPixes groupPixes, int row, int column, Color color)
        {
            double allR = 0;
            double allG = 0;
            double allB = 0;
            foreach (Pixe p in groupPixes.list)
            {
                allR += p.R;
                allG += p.G;
                allB += p.B;
            }
            int count = groupPixes.list.Count();
            if (color == Color.Red)
            {
                ledCollection.OriginalRGB[row, column][0, 0] = allR / count;
                ledCollection.OriginalRGB[row, column][0, 1] = allG / count;
                ledCollection.OriginalRGB[row, column][0, 2] = allB / count;
            }
            else if (color == Color.Green)
            {
                ledCollection.OriginalRGB[row, column][1, 0] = allR / count;
                ledCollection.OriginalRGB[row, column][1, 1] = allG / count;
                ledCollection.OriginalRGB[row, column][1, 2] = allB / count;
            }
            else if (color == Color.Blue)
            {
                ledCollection.OriginalRGB[row, column][2, 0] = allR / count;
                ledCollection.OriginalRGB[row, column][2, 1] = allG / count;
                ledCollection.OriginalRGB[row, column][2, 2] = allB / count;
            }
        }

        public void SetModGPAdjust()
        {
            SCP_STATUS_T status4 = SetModGPAdjust(Scp_wall.modpg[0].senderId);
        }

        public void SetHwmodGPDots()
        {
            SCP_STATUS_T status5 = SetHwmodGPDots(Scp_wall.modpg[0].senderId);
        }

        public void SetFullModGPAdjust()
        {
            SCP_STATUS_T status4 = SetFullModGPAdjust(Scp_wall.modpg[0].senderId);
        }

        //private List<int> CountDeadLed(DoubleMatrix[,] originalXYZ, Color color)
        //{
        //    List<int> deadList = new List<int>();
        //    int index = 0;
        //    if (color == Color.Red)
        //    {
        //        index = 0;
        //    }
        //    else if (color == Color.Green)
        //    {
        //        index = 1;
        //    }
        //    else if (color == Color.Blue)
        //    {
        //        index = 2;
        //    }

        //    double X = 0.0;
        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            X += originalXYZ[i, j][0, index];
        //        }
        //    }

        //    X = X / (partitionRow * partitionColumn);
        //    double XValue = X * 0.3;

        //    //将小于XrValue值看做LED坏点，将其剔除
        //    for (int i = 0; i < partitionRow; i++)
        //    {
        //        for (int j = 0; j < partitionColumn; j++)
        //        {
        //            if (originalXYZ[i, j][0, index] < XValue)
        //            {
        //                int num = i * partitionColumn + j;
        //                deadList.Add(num);
        //            }
        //        }
        //    }

        //    return deadList;
        //}

        //private Bitmap GetBitmap(int partitionNum, Color color)
        //{
        //    string directoryPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Vtron\\LEDCorrective";
        //    string fileName = String.Format("{0}\\{1}_{2}_{3}.JPG", directoryPath, id, partitionNum, color.Name);
        //    if (color == Color.Red)
        //    {
        //        fileName = String.Format("{0}\\{1}.JPG", directoryPath, "IMG_0001");
        //    }
        //    else if (color == Color.Green)
        //    {
        //        fileName = String.Format("{0}\\{1}.JPG", directoryPath, "IMG_0002");
        //    }
        //    else if (color == Color.Blue)
        //    {
        //        fileName = String.Format("{0}\\{1}.JPG", directoryPath, "IMG_0003");
        //    }
        //    Image imgInFile = Image.FromFile(fileName);
        //    Bitmap bitmap = new Bitmap(imgInFile);
        //    imgInFile.Dispose();

        //    return bitmap;
        //}

        //private DoubleMatrix[,] GetTargetXYZ(DoubleMatrix[,] originalXYZ, List<int> deadList, double XrWithoutDead, double YrWithoutDead, double ZrWithoutDead, double XgWithoutDead, double YgWithoutDead, double ZgWithoutDead, double XbWithoutDead, double YbWithoutDead, double ZbWithoutDead, double k)
        //{
        //    DoubleMatrix[,] targetXYZ = originalXYZ;
        //    double XrTarget = k * XrWithoutDead;
        //    double YrTarget = k * YrWithoutDead;
        //    double ZrTarget = k * ZrWithoutDead;

        //    double XgTarget = k * XgWithoutDead;
        //    double YgTarget = k * YgWithoutDead;
        //    double ZgTarget = k * ZgWithoutDead;

        //    double XbTarget = k * XbWithoutDead;
        //    double YbTarget = k * YbWithoutDead;
        //    double ZbTarget = k * ZbWithoutDead;

        //    double XR = 0.0;
        //    double PXR = 0.0;
        //    double YG = 0.0;
        //    double PYG = 0.0;
        //    double ZB = 0.0;
        //    double PZB = 0.0;

        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            int num = i * resolWidth + j;
        //            if (deadList.Contains(num))
        //            {
        //                continue;
        //            }

        //            if (targetXYZ[i, j][0, 0] >= XrTarget)
        //            {
        //                targetXYZ[i, j][0, 0] = XrTarget;
        //            }

        //            XR += (targetXYZ[i, j][0, 0] - XrWithoutDead) * (targetXYZ[i, j][0, 0] - XrWithoutDead);

        //            if (targetXYZ[i, j][1, 0] >= YrTarget)
        //            {
        //                targetXYZ[i, j][1, 0] = YrTarget;
        //            }

        //            if (targetXYZ[i, j][2, 0] >= ZrTarget)
        //            {
        //                targetXYZ[i, j][2, 0] = ZrTarget;
        //            }

        //            if (targetXYZ[i, j][0, 1] >= XgTarget)
        //            {
        //                targetXYZ[i, j][0, 1] = XgTarget;
        //            }

        //            if (targetXYZ[i, j][1, 1] >= YgTarget)
        //            {
        //                targetXYZ[i, j][1, 1] = YgTarget;
        //            }

        //            YG += (targetXYZ[i, j][1, 1] - YgWithoutDead) * (targetXYZ[i, j][1, 1] - YgWithoutDead);

        //            if (targetXYZ[i, j][2, 1] >= ZgTarget)
        //            {
        //                targetXYZ[i, j][2, 1] = ZgTarget;
        //            }

        //            if (targetXYZ[i, j][0, 2] >= XbTarget)
        //            {
        //                targetXYZ[i, j][0, 2] = XbTarget;
        //            }

        //            if (targetXYZ[i, j][1, 2] >= YbTarget)
        //            {
        //                targetXYZ[i, j][1, 2] = YbTarget;
        //            }

        //            if (targetXYZ[i, j][2, 2] >= ZbTarget)
        //            {
        //                targetXYZ[i, j][2, 2] = ZbTarget;
        //            }

        //            ZB += (targetXYZ[i, j][2, 2] - ZbWithoutDead) * (targetXYZ[i, j][2, 2] - ZbWithoutDead);
        //        }
        //    }


        //    int count = resolHeight * resolWidth - deadList.Count();
        //    XR = XR / count;
        //    XR = Math.Sqrt(XR);
        //    PXR = XR / XrWithoutDead;
        //    YG = YG / count;
        //    YG = Math.Sqrt(YG);
        //    PYG = YG / YgWithoutDead;
        //    ZB = ZB / count;
        //    ZB = Math.Sqrt(ZB);
        //    PZB = ZB / ZbWithoutDead;

        //    if (k <= 0.8 || (PXR <= 0.01 && PYG <= 0.01 && PZB <= 0.01))
        //    {
        //        return targetXYZ;
        //    }
        //    else
        //    {
        //        for (int i = 0; i < partitionRow; i++)
        //        {
        //            for (int j = 0; j < partitionColumn; j++)
        //            {
        //                int num = i * partitionColumn + j;
        //                if (deadList.Contains(num))
        //                {
        //                    continue;
        //                }
        //                XrWithoutDead += targetXYZ[i, j][0, 0];
        //                YrWithoutDead += targetXYZ[i, j][1, 0];
        //                ZrWithoutDead += targetXYZ[i, j][2, 0];

        //                XgWithoutDead += targetXYZ[i, j][0, 1];
        //                YgWithoutDead += targetXYZ[i, j][1, 1];
        //                ZgWithoutDead += targetXYZ[i, j][2, 1];

        //                XbWithoutDead += targetXYZ[i, j][0, 2];
        //                YbWithoutDead += targetXYZ[i, j][1, 2];
        //                ZbWithoutDead += targetXYZ[i, j][2, 2];
        //            }
        //        }

        //        XrWithoutDead = XrWithoutDead / count;
        //        YrWithoutDead = YrWithoutDead / count;
        //        ZrWithoutDead = ZrWithoutDead / count;

        //        XgWithoutDead = XgWithoutDead / count;
        //        YgWithoutDead = YgWithoutDead / count;
        //        ZgWithoutDead = ZgWithoutDead / count;

        //        XbWithoutDead = XbWithoutDead / count;
        //        YbWithoutDead = YbWithoutDead / count;
        //        ZbWithoutDead = ZbWithoutDead / count;


        //        return GetTargetXYZ(targetXYZ, deadList, XrWithoutDead, YrWithoutDead, ZrWithoutDead, XgWithoutDead, YgWithoutDead, ZgWithoutDead, XbWithoutDead, YbWithoutDead, ZbWithoutDead, k - 0.05);
        //    }
        //}

        public SCP_WALLS_T GetWall()
        {
            SCP_WALLID_T wallId = GetDefaultWallId();
            SCP_WALLS_T wall = GetWall(wallId);
            return wall;
        }

        /// <summary>
        /// 获取默认墙体ID
        /// </summary>
        /// <returns></returns>
        private SCP_WALLID_T GetDefaultWallId()
        {
            SCP_BODY_T body = new SCP_BODY_T();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_GET_DEFAULTWALLID;
            body.scp_datalen = 200;
            body.scp_data = new byte[200];

            SCP_HEADER_T header = new SCP_HEADER_T();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte;

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_WALLID_T wallId = default(SCP_WALLID_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_GET_DEFAULTWALLID)
                {
                    wallId = (SCP_WALLID_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_WALLID_T));
                }
            }

            return wallId;
        }

        /// <summary>
        /// 获取墙体信息
        /// </summary>
        /// <param name="wallId"></param>
        /// <returns></returns>
        /// <remarks>
        /// SCP_WALLID_T wallId = new SCP_WALLID_T();
        /// </remarks>
        private SCP_WALLS_T GetWall(SCP_WALLID_T wallId)
        {
            SCP_BODY_T4 body = new SCP_BODY_T4();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_GET_WALL;
            var dataByte = Utils.StructToBytes(wallId);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte;

            SCP_HEADER_T4 header = new SCP_HEADER_T4();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte;

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_WALLS_T wall = default(SCP_WALLS_T);
            SCP_HEADER_T3 response = communicationHandler.Handle<SCP_HEADER_T3>(header);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T3 a = (SCP_BODY_T3)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T3));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_GET_WALL)
                {
                    wall = (SCP_WALLS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_WALLS_T));
                }
            }

            return wall;
        }

        /// <summary>
        /// 获取扫描属性
        /// </summary>
        /// <returns></returns>
        public SCP_SCAN_T GetScan()
        {
            SCP_BODY_T44 body = new SCP_BODY_T44();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_GET_SCAN;
            SCP_SHOWID_T showId = new SCP_SHOWID_T();
            showId.senderId = Scp_wall.modpg[0].senderId;
            showId.modeGroupId = Scp_wall.modpg[0].modgpId;
            var showIdByte = Utils.StructToBytes(showId);
            body.scp_datalen = (uint)showIdByte.Count();
            body.scp_data = showIdByte;

            SCP_HEADER_T44 header = new SCP_HEADER_T44();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte;

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_SCAN_T scan = default(SCP_SCAN_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_GET_SCAN)
                {
                    scan = (SCP_SCAN_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_SCAN_T));
                }
            }

            return scan;
        }

        /// <summary>
        /// 设置扫描属性
        /// </summary>
        /// <returns></returns>
        public SCP_STATUS_T SetScan(SCP_SCAN_T scan)
        {
            SCP_BODY_T80 body = new SCP_BODY_T80();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_SET_SCAN;
            SCP_SETSCANREQUST_T showId = new SCP_SETSCANREQUST_T();
            showId.senderId = Scp_wall.modpg[0].senderId;
            showId.modeGroupId = Scp_wall.modpg[0].modgpId;
            showId.scan = scan;
            var showIdByte = Utils.StructToBytes(showId);
            body.scp_datalen = (uint)showIdByte.Count();
            body.scp_data = showIdByte;

            SCP_HEADER_T80 header = new SCP_HEADER_T80();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte;

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_STATUS_T result = default(SCP_STATUS_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
                {
                    result = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
                }
            }

            return result;
        }

        /// <summary>
        /// 逐点校正
        /// </summary>
        /// <returns></returns>
        private SCP_STATUS_T SetModGPAdjust(SCP_SENDERID_T senderId)
        {
            SCP_ROW_ADJUST_T[] rowAdjusts = new SCP_ROW_ADJUST_T[resolHeight];
            for (int i = 0; i < resolHeight; i++)
            {
                SCP_PIXEL_ADJUST_T[] pixelAdjusts = new SCP_PIXEL_ADJUST_T[resolWidth];
                for (int j = 0; j < resolWidth; j++)
                {
                    int k = i / partitionRow;
                    int l = j / partitionColumn;
                    int num = k * SeparateColumn + l;

                    DoubleMatrix doubleMatrix = ledCollections[num].KRGB[i - k * partitionRow, j - l * partitionColumn];
                    //亮场颜色分量校正系数
                    SCP_COMP_ADJUST_COEFF_T brightRed = new SCP_COMP_ADJUST_COEFF_T();
                    brightRed.red = (ushort)doubleMatrix[0, 0];
                    brightRed.green = (ushort)doubleMatrix[1, 0];
                    brightRed.blue = (ushort)doubleMatrix[2, 0];

                    SCP_COMP_ADJUST_COEFF_T brightGreen = new SCP_COMP_ADJUST_COEFF_T();
                    brightGreen.red = (ushort)doubleMatrix[0, 1];
                    brightGreen.green = (ushort)doubleMatrix[1, 1];
                    brightGreen.blue = (ushort)doubleMatrix[2, 1];

                    SCP_COMP_ADJUST_COEFF_T brightBlue = new SCP_COMP_ADJUST_COEFF_T();
                    brightBlue.red = (ushort)doubleMatrix[0, 2];
                    brightBlue.green = (ushort)doubleMatrix[1, 2];
                    brightBlue.blue = (ushort)doubleMatrix[2, 2];

                    //亮场校正系数矩阵
                    SCP_COLOR_ADJUST_MATRIX_T brightColorAdjustMatrix = new SCP_COLOR_ADJUST_MATRIX_T();
                    brightColorAdjustMatrix.red = brightRed;
                    brightColorAdjustMatrix.green = brightGreen;
                    brightColorAdjustMatrix.blue = brightBlue;

                    //单点校正系数
                    SCP_PIXEL_ADJUST_T pixelAdjust = new SCP_PIXEL_ADJUST_T();
                    pixelAdjust.bright = brightColorAdjustMatrix;

                    pixelAdjusts[j] = pixelAdjust;
                }

                //行校正系数
                SCP_ROW_ADJUST_T rowAdjust = new SCP_ROW_ADJUST_T();
                rowAdjust.row = (ushort)i;
                rowAdjust.pixelNum = (ushort)resolWidth;
                rowAdjust.adjustDatas = pixelAdjusts;

                rowAdjusts[i] = rowAdjust;
            }

            //暗场颜色分量校正系数
            SCP_COMP_ADJUST_COEFF_T darkRed = new SCP_COMP_ADJUST_COEFF_T();
            darkRed.red = 0;
            darkRed.green = 0;
            darkRed.blue = 0;

            SCP_COMP_ADJUST_COEFF_T darkGreen = new SCP_COMP_ADJUST_COEFF_T();
            darkGreen.red = 0;
            darkGreen.green = 0;
            darkGreen.blue = 0;

            SCP_COMP_ADJUST_COEFF_T darkBlue = new SCP_COMP_ADJUST_COEFF_T();
            darkBlue.red = 0;
            darkBlue.green = 0;
            darkBlue.blue = 0;

            //暗场校正系数矩阵
            SCP_COLOR_ADJUST_MATRIX_T darkColorAdjustMatrix = new SCP_COLOR_ADJUST_MATRIX_T();
            darkColorAdjustMatrix.red = darkRed;
            darkColorAdjustMatrix.green = darkGreen;
            darkColorAdjustMatrix.blue = darkBlue;

            //模组校正系数
            SCP_MODGP_ADJUST_T adjust = new SCP_MODGP_ADJUST_T();
            adjust.id = 0;
            adjust.dark = darkColorAdjustMatrix;
            adjust.rowNum = (ushort)resolHeight;
            adjust.rowAdjustDatas = rowAdjusts;

            SCP_MODGPADJUST_T modGPAdjust = new SCP_MODGPADJUST_T();
            modGPAdjust.senderId = senderId;
            modGPAdjust.ModeGPAdjust = adjust;

            SCP_BODY_T3 body = new SCP_BODY_T3();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_ADJUST_MODGPDOTS;
            var dataByte = Utils.StructToBytes(modGPAdjust);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte.Concat(new byte[664384 - body.scp_datalen]).ToArray();

            SCP_HEADER_T3 header = new SCP_HEADER_T3();
            header.scp_id = 0;
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte.Concat(new byte[664394 - header.scp_datalen]).ToArray();

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_STATUS_T status = default(SCP_STATUS_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
                {
                    status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
                }
            }

            return status;
        }

        /// <summary>
        /// 全屏逐点校正
        /// </summary>
        /// <returns></returns>
        private SCP_STATUS_T SetFullModGPAdjust(SCP_SENDERID_T senderId)
        {
            SCP_ROW_ADJUST_T[] rowAdjusts = new SCP_ROW_ADJUST_T[resolHeight];
            for (int i = 0; i < resolHeight; i++)
            {
                SCP_PIXEL_ADJUST_T[] pixelAdjusts = new SCP_PIXEL_ADJUST_T[resolWidth];
                for (int j = 0; j < resolWidth; j++)
                {
                    int k = i / splitScreenRow;
                    int l = j / splitScreenColumn;
                    int num = k * SplitScreenSeparateColumn + l;

                    DoubleMatrix doubleMatrix = splitScreenLedCollections[num].KRGB[i - k * splitScreenRow, j - l * splitScreenColumn];
                    //亮场颜色分量校正系数
                    SCP_COMP_ADJUST_COEFF_T brightRed = new SCP_COMP_ADJUST_COEFF_T();
                    brightRed.red = (ushort)doubleMatrix[0, 0];
                    brightRed.green = (ushort)doubleMatrix[1, 0];
                    brightRed.blue = (ushort)doubleMatrix[2, 0];

                    SCP_COMP_ADJUST_COEFF_T brightGreen = new SCP_COMP_ADJUST_COEFF_T();
                    brightGreen.red = (ushort)doubleMatrix[0, 1];
                    brightGreen.green = (ushort)doubleMatrix[1, 1];
                    brightGreen.blue = (ushort)doubleMatrix[2, 1];

                    SCP_COMP_ADJUST_COEFF_T brightBlue = new SCP_COMP_ADJUST_COEFF_T();
                    brightBlue.red = (ushort)doubleMatrix[0, 2];
                    brightBlue.green = (ushort)doubleMatrix[1, 2];
                    brightBlue.blue = (ushort)doubleMatrix[2, 2];

                    //亮场校正系数矩阵
                    SCP_COLOR_ADJUST_MATRIX_T brightColorAdjustMatrix = new SCP_COLOR_ADJUST_MATRIX_T();
                    brightColorAdjustMatrix.red = brightRed;
                    brightColorAdjustMatrix.green = brightGreen;
                    brightColorAdjustMatrix.blue = brightBlue;

                    //单点校正系数
                    SCP_PIXEL_ADJUST_T pixelAdjust = new SCP_PIXEL_ADJUST_T();
                    pixelAdjust.bright = brightColorAdjustMatrix;

                    pixelAdjusts[j] = pixelAdjust;
                }

                //行校正系数
                SCP_ROW_ADJUST_T rowAdjust = new SCP_ROW_ADJUST_T();
                rowAdjust.row = (ushort)i;
                rowAdjust.pixelNum = (ushort)resolWidth;
                rowAdjust.adjustDatas = pixelAdjusts;

                rowAdjusts[i] = rowAdjust;
            }

            //暗场颜色分量校正系数
            SCP_COMP_ADJUST_COEFF_T darkRed = new SCP_COMP_ADJUST_COEFF_T();
            darkRed.red = 0;
            darkRed.green = 0;
            darkRed.blue = 0;

            SCP_COMP_ADJUST_COEFF_T darkGreen = new SCP_COMP_ADJUST_COEFF_T();
            darkGreen.red = 0;
            darkGreen.green = 0;
            darkGreen.blue = 0;

            SCP_COMP_ADJUST_COEFF_T darkBlue = new SCP_COMP_ADJUST_COEFF_T();
            darkBlue.red = 0;
            darkBlue.green = 0;
            darkBlue.blue = 0;

            //暗场校正系数矩阵
            SCP_COLOR_ADJUST_MATRIX_T darkColorAdjustMatrix = new SCP_COLOR_ADJUST_MATRIX_T();
            darkColorAdjustMatrix.red = darkRed;
            darkColorAdjustMatrix.green = darkGreen;
            darkColorAdjustMatrix.blue = darkBlue;

            //模组校正系数
            SCP_MODGP_ADJUST_T adjust = new SCP_MODGP_ADJUST_T();
            adjust.id = 0;
            adjust.dark = darkColorAdjustMatrix;
            adjust.rowNum = (ushort)resolHeight;
            adjust.rowAdjustDatas = rowAdjusts;

            SCP_MODGPADJUST_T modGPAdjust = new SCP_MODGPADJUST_T();
            modGPAdjust.senderId = senderId;
            modGPAdjust.ModeGPAdjust = adjust;

            SCP_BODY_T3 body = new SCP_BODY_T3();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_ADJUST_MODGPDOTS;
            var dataByte = Utils.StructToBytes(modGPAdjust);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte.Concat(new byte[664384 - body.scp_datalen]).ToArray();

            SCP_HEADER_T3 header = new SCP_HEADER_T3();
            header.scp_id = 0;
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte.Concat(new byte[664394 - header.scp_datalen]).ToArray();

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_STATUS_T status = default(SCP_STATUS_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
                {
                    status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
                }
            }

            return status;
        }

        /// <summary>
        /// 固化逐点校正到硬件
        /// </summary>
        /// <param name="wallId"></param>
        /// <returns></returns>
        private SCP_STATUS_T SetHwmodGPDots(SCP_SENDERID_T senderId)
        {
            SCP_SET_HWMODGPDOTS_T hwmodGPDots = new SCP_SET_HWMODGPDOTS_T();
            hwmodGPDots.senderId = senderId;
            hwmodGPDots.modeGroupId = Scp_wall.modpg[0].modgpId;

            SCP_BODY_T44 body = new SCP_BODY_T44();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_SET_HWMODGPDOTS;
            var dataByte = Utils.StructToBytes(hwmodGPDots);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

            SCP_HEADER_T44 header = new SCP_HEADER_T44();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_STATUS_T status = default(SCP_STATUS_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
                {
                    status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
                }
            }
            return status;
        }

        /// <summary>
        /// 获取逐点校正使能属性
        /// </summary>
        /// <param name="wallId"></param>
        /// <returns></returns>
        private SCP_ADJUSTDOTS_T GetAdjustDots(SCP_SENDERID_T senderId)
        {
            SCP_GET_ADJUSTDOTS_T getAdjustDots = new SCP_GET_ADJUSTDOTS_T();
            getAdjustDots.senderId = senderId;
            getAdjustDots.modeGroupId = Scp_wall.modpg[0].modgpId;

            SCP_BODY_T44 body = new SCP_BODY_T44();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_GET_ADJUSTDOTS;
            var dataByte = Utils.StructToBytes(getAdjustDots);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

            SCP_HEADER_T44 header = new SCP_HEADER_T44();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_ADJUSTDOTS_T adjustDots = default(SCP_ADJUSTDOTS_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_GET_ADJUSTDOTS)
                {
                    adjustDots = (SCP_ADJUSTDOTS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_ADJUSTDOTS_T));
                }
            }
            return adjustDots;
        }

        /// <summary>
        /// 设置逐点校正使能属性
        /// </summary>
        /// <param name="wallId"></param>
        /// <returns></returns>
        private SCP_STATUS_T SetAdjustDots(SCP_SENDERID_T senderId, bool isEnable)
        {
            SCP_ADJUSTDOTS_T adjustDots = new SCP_ADJUSTDOTS_T();
            adjustDots.enable = (byte)(isEnable ? 1 : 0);

            SCP_SET_ADJUSTDOTS_T getAdjustDots = new SCP_SET_ADJUSTDOTS_T();
            getAdjustDots.senderId = senderId;
            getAdjustDots.modeGroupId = Scp_wall.modpg[0].modgpId;
            getAdjustDots.adjustDots = adjustDots;

            SCP_BODY_T body = new SCP_BODY_T();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_SET_ADJUSTDOTS;
            var dataByte = Utils.StructToBytes(getAdjustDots);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

            SCP_HEADER_T header = new SCP_HEADER_T();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_STATUS_T status = default(SCP_STATUS_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
                {
                    status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
                }
            }
            return status;
        }

        /// <summary>
        /// 获取色温属性
        /// </summary>
        /// <returns></returns>
        public SCP_COLORTEMP_T GetColorTemp(SCP_GET_COLORTEMP getColorTemp)
        {
            SCP_BODY_T2 body = new SCP_BODY_T2();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_GET_COLORTEMP;
            var dataByte = Utils.StructToBytes(getColorTemp);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte;

            SCP_HEADER_T2 header = new SCP_HEADER_T2();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte;

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_COLORTEMP_T colorTemp = default(SCP_COLORTEMP_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_GET_COLORTEMP)
                {
                    colorTemp = (SCP_COLORTEMP_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_COLORTEMP_T));
                }
            }
            return colorTemp;
        }

        /// <summary>
        /// 设置色温属性
        /// </summary>
        public SCP_STATUS_T SetColorTemp(SCP_SET_COLORTEMP colorTemp)//SCP_COLORTEMP_T colorTemp)
        {
            SCP_BODY_T8 body = new SCP_BODY_T8();
            body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_SET_COLORTEMP;
            var dataByte = Utils.StructToBytes(colorTemp);
            body.scp_datalen = (uint)dataByte.Count();
            body.scp_data = dataByte;

            SCP_HEADER_T8 header = new SCP_HEADER_T8();
            header.scp_type = (ushort)ScpType.SCP_COMMAND;
            var bodyByte = Utils.StructToBytes(body);
            header.scp_datalen = (uint)bodyByte.Count();
            header.scp_data = bodyByte;

            ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
            SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
            SCP_STATUS_T status = default(SCP_STATUS_T);
            if (response.scp_type == (ushort)ScpType.SCP_RETURN)
            {
                SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
                if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
                {
                    status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
                }
            }
            return status;
        }

        //public void ShowMeasurementImage()

        //public void Start()
        //{
        //    DoubleMatrix[,] originalRGB = new DoubleMatrix[resolWidth, resolHeight];
        //    DoubleMatrix[,] KRGB = new DoubleMatrix[resolWidth, resolHeight];

        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            originalRGB[i, j] = new double[3, 3] {{0,0,0},
        //                                                  {0,0,0},
        //                                                  {0,0,0}};
        //            KRGB[i, j] = new double[3, 3] {{0,0,0},
        //                                           {0,0,0},
        //                                           {0,0,0}};
        //        }
        //    }
        //    PictureDataCollection(originalRGB);
        //    CorrectionAlgorithmAnalysis(originalRGB, KRGB);
        //    Corrective(KRGB);
        //}

        //public void Stop()
        //{
        //}

        //private void PictureDataCollection(DoubleMatrix[,] originalRGB)
        //{
        //    Image redImgInFile = Image.FromFile("D:\\test33.JPG");
        //    Bitmap redBitmap = new Bitmap(redImgInFile);
        //    redImgInFile.Dispose();
        //    Image greenImgInFile = Image.FromFile("D:\\test34.JPG");
        //    Bitmap greenBitmap = new Bitmap(greenImgInFile);
        //    greenImgInFile.Dispose();
        //    Image blueImgInFile = Image.FromFile("D:\\test35.JPG");
        //    Bitmap blueBitmap = new Bitmap(blueImgInFile);
        //    blueImgInFile.Dispose();

        //    int minimumRed = 230;
        //    int minimumGreen = 230;
        //    int minimumBlue = 230;

        //    Parallel.Invoke(() =>
        //    {
        //        RedPictureDataCollection(redBitmap, minimumRed, originalRGB);
        //    },
        //    () =>
        //    {
        //        GreenPictureDataCollection(greenBitmap, minimumGreen, originalRGB);
        //    },
        //    () =>
        //    {
        //        BluePictureDataCollection(blueBitmap, minimumBlue, originalRGB);
        //    });
        //}

        //private void RedPictureDataCollection(Bitmap redBitmap, int minimumRed, DoubleMatrix[,] originalRGB)
        //{
        //    List<GroupPixes> RedColors = new List<GroupPixes>();
        //    List<Pixe> lastLineRedColors = new List<Pixe>();
        //    List<Pixe> thisLineRedColors = new List<Pixe>();

        //    for (int i = 0; i < redBitmap.Height; i++)
        //    {
        //        lastLineRedColors = thisLineRedColors;
        //        thisLineRedColors = new List<Pixe>();
        //        for (int j = 0; j < redBitmap.Width; j++)
        //        {
        //            Color redColor = redBitmap.GetPixel(j, i);
        //            if (redColor.R > minimumRed)
        //            {
        //                Pixe pixe = new Pixe();
        //                pixe.R = redColor.R;
        //                pixe.G = redColor.G;
        //                pixe.B = redColor.B;
        //                pixe.X = j;
        //                pixe.Y = i;
        //                Pixe leftColor = null;
        //                Pixe upColor = null;
        //                if (j > 1)
        //                {
        //                    leftColor = thisLineRedColors.FirstOrDefault(c => c.X == j - 1 && c.Y == i);//查找左边的点
        //                }
        //                if (i > 1)
        //                {
        //                    upColor = lastLineRedColors.FirstOrDefault(c => c.X == j && c.Y == i - 1);//查找上边的点
        //                }
        //                if (leftColor != null)
        //                {
        //                    if (upColor != null)
        //                    {
        //                        GroupPixes groupPixes = upColor.GroupPixes;
        //                        if (upColor.GroupPixes.Id != leftColor.GroupPixes.Id)
        //                        {
        //                            RedColors.Remove(leftColor.GroupPixes);

        //                            foreach (Pixe p in leftColor.GroupPixes.Pixes)
        //                            {
        //                                p.GroupPixes = groupPixes;
        //                                groupPixes.Pixes.Add(p);
        //                            }
        //                        }
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                    else
        //                    {
        //                        GroupPixes groupPixes = leftColor.GroupPixes;
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                }
        //                else
        //                {
        //                    if (upColor != null)
        //                    {
        //                        GroupPixes groupPixes = upColor.GroupPixes;
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                    else
        //                    {
        //                        GroupPixes groupPixes = new GroupPixes();
        //                        groupPixes.Id = Guid.NewGuid();
        //                        groupPixes.Pixes = new List<Pixe>();
        //                        groupPixes.Pixes.Add(pixe);
        //                        pixe.GroupPixes = groupPixes;

        //                        RedColors.Add(groupPixes);
        //                    }
        //                }
        //                thisLineRedColors.Add(pixe);
        //            }
        //        }
        //    }

        //    RedColors.RemoveAll(gp => gp.Pixes.Count() < 10);

        //    if (RedColors.Count() != resolHeight * resolWidth)
        //    {
        //        throw new Exception("拍照技术不过关，计算出来的红色LED点不对！");
        //    }
        //    else
        //    {
        //        for (int i = 0; i < resolHeight; i++)
        //        {
        //            for (int j = 0; j < resolWidth; j++)
        //            {
        //                GroupPixes groupPixes = RedColors[i * resolWidth + j];
        //                double allR = 0;
        //                double allG = 0;
        //                double allB = 0;
        //                foreach (Pixe p in groupPixes.Pixes)
        //                {
        //                    allR += p.R;
        //                    allG += p.G;
        //                    allB += p.B;
        //                }
        //                int count = groupPixes.Pixes.Count();
        //                originalRGB[i, j][0, 0] = allR / count;
        //                originalRGB[i, j][1, 0] = allG / count;
        //                originalRGB[i, j][2, 0] = allB / count;
        //            }
        //        }
        //    }

        //    redBitmap.Dispose();
        //}

        //private void GreenPictureDataCollection(Bitmap greenBitmap, int minimumGreen, DoubleMatrix[,] originalRGB)
        //{
        //    List<GroupPixes> GreenColors = new List<GroupPixes>();
        //    List<Pixe> lastLineGreenColors = new List<Pixe>();
        //    List<Pixe> thisLineGreenColors = new List<Pixe>();

        //    for (int i = 0; i < greenBitmap.Height; i++)
        //    {
        //        lastLineGreenColors = thisLineGreenColors;
        //        thisLineGreenColors = new List<Pixe>();
        //        for (int j = 0; j < greenBitmap.Width; j++)        //        {
        //            Color greenColor = greenBitmap.GetPixel(j, i);
        //            if (greenColor.G > minimumGreen)
        //            {
        //                Pixe pixe = new Pixe();
        //                pixe.R = greenColor.R;
        //                pixe.G = greenColor.G;
        //                pixe.B = greenColor.B;
        //                pixe.X = j;
        //                pixe.Y = i;
        //                Pixe leftColor = null;
        //                Pixe upColor = null;
        //                if (j > 1)
        //                {
        //                    leftColor = thisLineGreenColors.FirstOrDefault(c => c.X == j - 1 && c.Y == i);//查找左边的点
        //                }
        //                if (i > 1)
        //                {
        //                    upColor = lastLineGreenColors.FirstOrDefault(c => c.X == j && c.Y == i - 1);//查找上边的点
        //                }
        //                if (leftColor != null)
        //                {
        //                    if (upColor != null)
        //                    {
        //                        GroupPixes groupPixes = upColor.GroupPixes;
        //                        if (upColor.GroupPixes.Id != leftColor.GroupPixes.Id)
        //                        {
        //                            GreenColors.Remove(leftColor.GroupPixes);

        //                            foreach (Pixe p in leftColor.GroupPixes.Pixes)
        //                            {
        //                                p.GroupPixes = groupPixes;
        //                                groupPixes.Pixes.Add(p);
        //                            }
        //                        }
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                    else
        //                    {
        //                        GroupPixes groupPixes = leftColor.GroupPixes;
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                }
        //                else
        //                {
        //                    if (upColor != null)
        //                    {
        //                        GroupPixes groupPixes = upColor.GroupPixes;
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                    else
        //                    {
        //                        GroupPixes groupPixes = new GroupPixes();
        //                        groupPixes.Id = Guid.NewGuid();
        //                        groupPixes.Pixes = new List<Pixe>();
        //                        groupPixes.Pixes.Add(pixe);
        //                        pixe.GroupPixes = groupPixes;

        //                        GreenColors.Add(groupPixes);
        //                    }
        //                }
        //                thisLineGreenColors.Add(pixe);
        //            }
        //        }
        //    }

        //    GreenColors.RemoveAll(gp => gp.Pixes.Count() < 10);

        //    if (GreenColors.Count() != resolHeight * resolWidth)
        //    {
        //        throw new Exception("拍照技术不过关，计算出来的绿色LED点不对！");
        //    }
        //    else
        //    {
        //        for (int i = 0; i < resolHeight; i++)
        //        {
        //            for (int j = 0; j < resolWidth; j++)
        //            {
        //                GroupPixes groupPixes = GreenColors[i * resolWidth + j];
        //                double allR = 0;
        //                double allG = 0;
        //                double allB = 0;
        //                foreach (Pixe p in groupPixes.Pixes)
        //                {
        //                    allR += p.R;
        //                    allG += p.G;
        //                    allB += p.B;
        //                }
        //                int count = groupPixes.Pixes.Count();
        //                originalRGB[i, j][0, 1] = allR / count;
        //                originalRGB[i, j][1, 1] = allG / count;
        //                originalRGB[i, j][2, 1] = allB / count;
        //            }
        //        }
        //    }

        //    greenBitmap.Dispose();
        //}

        //private void BluePictureDataCollection(Bitmap blueBitmap, int minimumBlue, DoubleMatrix[,] originalRGB)
        //{
        //    List<GroupPixes> BlueColors = new List<GroupPixes>();
        //    List<Pixe> lastLineBlueColors = new List<Pixe>();
        //    List<Pixe> thisLineBlueColors = new List<Pixe>();

        //    for (int i = 0; i < blueBitmap.Height; i++)
        //    {
        //        lastLineBlueColors = thisLineBlueColors;
        //        thisLineBlueColors = new List<Pixe>();
        //        for (int j = 0; j < blueBitmap.Width; j++)
        //        {
        //            Color blueColor = blueBitmap.GetPixel(j, i);
        //            if (blueColor.B > minimumBlue)
        //            {
        //                Pixe pixe = new Pixe();
        //                pixe.R = blueColor.R;
        //                pixe.G = blueColor.G;
        //                pixe.B = blueColor.B;
        //                pixe.X = j;
        //                pixe.Y = i;
        //                Pixe leftColor = null;
        //                Pixe upColor = null;
        //                if (j > 1)
        //                {
        //                    leftColor = thisLineBlueColors.FirstOrDefault(c => c.X == j - 1 && c.Y == i);//查找左边的点
        //                }
        //                if (i > 1)
        //                {
        //                    upColor = lastLineBlueColors.FirstOrDefault(c => c.X == j && c.Y == i - 1);//查找上边的点
        //                }
        //                if (leftColor != null)
        //                {
        //                    if (upColor != null)
        //                    {
        //                        GroupPixes groupPixes = upColor.GroupPixes;
        //                        if (upColor.GroupPixes.Id != leftColor.GroupPixes.Id)
        //                        {
        //                            BlueColors.Remove(leftColor.GroupPixes);

        //                            foreach (Pixe p in leftColor.GroupPixes.Pixes)
        //                            {
        //                                p.GroupPixes = groupPixes;
        //                                groupPixes.Pixes.Add(p);
        //                            }
        //                        }
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                    else
        //                    {
        //                        GroupPixes groupPixes = leftColor.GroupPixes;
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                }
        //                else
        //                {
        //                    if (upColor != null)
        //                    {
        //                        GroupPixes groupPixes = upColor.GroupPixes;
        //                        pixe.GroupPixes = groupPixes;
        //                        groupPixes.Pixes.Add(pixe);
        //                    }
        //                    else
        //                    {
        //                        GroupPixes groupPixes = new GroupPixes();
        //                        groupPixes.Id = Guid.NewGuid();
        //                        groupPixes.Pixes = new List<Pixe>();
        //                        groupPixes.Pixes.Add(pixe);
        //                        pixe.GroupPixes = groupPixes;

        //                        BlueColors.Add(groupPixes);
        //                    }
        //                }
        //                thisLineBlueColors.Add(pixe);
        //            }
        //        }
        //    }

        //    BlueColors.RemoveAll(gp => gp.Pixes.Count() < 10);

        //    if (BlueColors.Count() != resolHeight * resolWidth)
        //    {
        //        throw new Exception("拍照技术不过关，计算出来的蓝色LED点不对！");
        //    }
        //    else
        //    {
        //        for (int i = 0; i < resolHeight; i++)
        //        {
        //            for (int j = 0; j < resolWidth; j++)
        //            {
        //                GroupPixes groupPixes = BlueColors[i * resolWidth + j];
        //                double allR = 0;
        //                double allG = 0;
        //                double allB = 0;
        //                foreach (Pixe p in groupPixes.Pixes)
        //                {
        //                    allR += p.R;
        //                    allG += p.G;
        //                    allB += p.B;
        //                }
        //                int count = groupPixes.Pixes.Count();
        //                originalRGB[i, j][0, 2] = allR / count;
        //                originalRGB[i, j][1, 2] = allG / count;
        //                originalRGB[i, j][2, 2] = allB / count;
        //            }
        //        }
        //    }

        //    blueBitmap.Dispose();
        //}

        //private void CorrectionAlgorithmAnalysis(DoubleMatrix[,] originalRGB, DoubleMatrix[,] KRGB)
        //{
        //    #region 将RGB三种颜色的RGB像素值转换为XYZ空间值

        //    DoubleMatrix[,] originalXYZ = new DoubleMatrix[resolHeight, resolWidth];
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            originalXYZ[i, j] = new double[3, 3];
        //            originalXYZ[i, j].Columns[0] = sRGB * originalRGB[i, j].Columns[0];
        //            originalXYZ[i, j].Columns[1] = sRGB * originalRGB[i, j].Columns[1];
        //            originalXYZ[i, j].Columns[2] = sRGB * originalRGB[i, j].Columns[2];
        //        }
        //    }

        //    #endregion

        //    #region 剔除坏点

        //    //红
        //    List<int> deadList = new List<int>();
        //    double Xr = 0.0;
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            Xr += originalXYZ[i, j][0, 0];
        //        }
        //    }
        //    Xr = Xr / (resolHeight * resolWidth);
        //    double XrValue = Xr * 0.3;

        //    //将小于XrValue值看做LED坏点，将其剔除
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            if (originalXYZ[i, j][0, 0] < XrValue)
        //            {
        //                int num = i * resolWidth + j;
        //                if (!deadList.Contains(num))
        //                {
        //                    deadList.Add(num);
        //                }
        //            }
        //        }
        //    }

        //    //绿
        //    double Xg = 0.0;
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            Xg += originalXYZ[i, j][1, 1];
        //        }
        //    }
        //    Xg = Xg / (resolHeight * resolWidth);
        //    double XgValue = Xr * 0.3;

        //    //将小于XgValue值看做LED坏点，将其剔除
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            if (originalXYZ[i, j][1, 1] < XgValue)
        //            {
        //                int num = i * resolWidth + j;
        //                if (!deadList.Contains(num))
        //                {
        //                    deadList.Add(num);
        //                }
        //            }
        //        }
        //    }

        //    //蓝
        //    double Xb = 0.0;
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            Xb += originalXYZ[i, j][2, 2];
        //        }
        //    }
        //    Xb = Xb / (resolHeight * resolWidth);
        //    double XbValue = Xr * 0.3;

        //    //将小于XbValue值看做LED坏点，将其剔除
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            if (originalXYZ[i, j][2, 2] < XbValue)
        //            {
        //                int num = i * resolWidth + j;
        //                if (!deadList.Contains(num))
        //                {
        //                    deadList.Add(num);
        //                }
        //            }
        //        }
        //    }

        //    #endregion

        //    #region 求目标三刺激值

        //    double XrWithoutDead = 0.0;
        //    double XgWithoutDead = 0.0;
        //    double XbWithoutDead = 0.0;
        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            int num = i * resolWidth + j;
        //            if (deadList.Contains(num))
        //            {
        //                continue;
        //            }
        //            XrWithoutDead += originalXYZ[i, j][0, 0];
        //            XgWithoutDead += originalXYZ[i, j][1, 1];
        //            XbWithoutDead += originalXYZ[i, j][2, 2];
        //        }
        //    }

        //    int count = resolHeight * resolWidth - deadList.Count();
        //    XrWithoutDead = XrWithoutDead / count;
        //    XgWithoutDead = XgWithoutDead / count;
        //    XbWithoutDead = XbWithoutDead / count;

        //    DoubleMatrix[,] targetXYZ = GetTargetXYZ(originalXYZ, deadList, XrWithoutDead, XgWithoutDead, XbWithoutDead, 1.0);

        //    #endregion

        //    #region 求补偿系数

        //    for (int i = 0; i < resolHeight; i++)
        //    {
        //        for (int j = 0; j < resolWidth; j++)
        //        {
        //            DoubleMatrix originalRGBInverse = originalRGB[i, j].Inverse;
        //            DoubleMatrix T = originalMaximumColor * originalRGBInverse;
        //            DoubleMatrix TsRGBInverse = T * sRGBInverse;

        //            KRGB[i, j].Columns[0] = TsRGBInverse * targetXYZ[i, j].Columns[0];
        //            KRGB[i, j].Columns[1] = TsRGBInverse * targetXYZ[i, j].Columns[1];
        //            KRGB[i, j].Columns[2] = TsRGBInverse * targetXYZ[i, j].Columns[2];

        //            for (int k = 0; k < 3; k++)
        //            {
        //                for (int l = 0; l < 3; l++)
        //                {
        //                    if (KRGB[i, j][k, l] < 0)
        //                    {
        //                        KRGB[i, j][k, l] = 0;
        //                    }

        //                    if (KRGB[i, j][k, l] > 255)
        //                    {
        //                        KRGB[i, j][k, l] = 255;
        //                    }
        //                }
        //            }

        //            KRGB[i, j] = KRGB[i, j] * TInverse;

        //            for (int k = 0; k < 3; k++)
        //            {
        //                for (int l = 0; l < 3; l++)
        //                {
        //                    if (KRGB[i, j][k, l] > 1)
        //                    {
        //                        KRGB[i, j][k, l] = 1;
        //                    }
        //                }
        //            }

        //            KRGB[i, j] = KRGB[i, j] * 65535;
        //        }
        //    }

        //    #endregion
        //}

        //private void Corrective(DoubleMatrix[,] KRGB)
        //{
        ////获取墙体默认Id
        //SCP_WALLID_T wallId = GetDefaultWallId();

        ////获取墙体信息
        //SCP_WALLS_T walls = GetWalls(wallId);
        //SCP_WALLID_T wallId = new SCP_WALLID_T();
        //wallId.scp_wallid = 0xffffffff; /*0xffffffff表示所有墙体,其他表示指定墙体*/
        //SCP_WALLS_T walls = GetWall(wallId);

        //显示模组Id
        //SCP_STATUS_T status = ShowId(walls.wall[0].modpg[0].senderId);

        //关闭墙体
        //SCP_STATUS_T status1 = WallClose(wallId);

        //打开墙体
        //SCP_STATUS_T status2 = WallClose(wallId);

        //获取系统时间
        //SCP_DATETIME_T dateTime = GetSystemTime(walls.wall[0].modpg[0].senderId);

        //SCP_ADJUSTDOTS_T adjustDots = GetAdjustDots(walls.wall[0].modpg[0].senderId);
        //if (adjustDots.enable == 0)
        //{
        //   SCP_STATUS_T status3 = SetAdjustDots(walls.wall[0].modpg[0].senderId);
        //   adjustDots = GetAdjustDots(walls.wall[0].modpg[0].senderId);
        //}

        //LED逐点校正
        //SCP_STATUS_T status4 = SetModGPAdjust(walls.wall[0].modpg[0].senderId, KRGB);

        //固化逐点校正到硬件
        //SCP_STATUS_T status5 = SetHwmodGPDots(walls.wall[0].modpg[0].senderId);

        //获取发送器所有测试图片
        //SCP_GET_ALLTESTPIC_T allTestPic = GetAllTestPic(walls.wall[0].modpg[0].senderId);

        //设置发送器测试图片
        //SCP_STATUS_T status6 = SetAllTestPic(walls.wall[0].modpg[0].senderId);

        //设置模组测试图片
        //SCP_STATUS_T status7 = SetModTestPic(walls.wall[0].modpg[0].senderId);
        //}

        ///// <summary>
        ///// 显示模组Id
        ///// </summary>
        ///// <param name="senderId"></param>
        ///// <returns></returns>
        //private SCP_STATUS_T ShowId(SCP_SENDERID_T senderId)
        //{
        //    SCP_SHOWID_T showId = new SCP_SHOWID_T();
        //    showId.senderId = senderId;
        //    showId.modeGroupId = 0xffff;//0x0000表示取消显示；0xffff表示所有模组

        //    SCP_BODY_T body = new SCP_BODY_T();
        //    body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_SHOWID;
        //    var dataByte = Utils.StructToBytes(showId);
        //    body.scp_datalen = (uint)dataByte.Count();
        //    body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

        //    SCP_HEADER_T header = new SCP_HEADER_T();
        //    header.scp_type = (ushort)ScpType.SCP_COMMAND;
        //    var bodyByte = Utils.StructToBytes(body);
        //    header.scp_datalen = (uint)bodyByte.Count();
        //    header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

        //    ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
        //    SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
        //    SCP_STATUS_T status = default(SCP_STATUS_T);
        //    if (response.scp_type == (ushort)ScpType.SCP_RETURN)
        //    {
        //        SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
        //        if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
        //        {
        //            status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
        //        }
        //    }
        //    return status;
        //}

        ///// <summary>
        ///// 关闭墙体
        ///// </summary>
        ///// <param name="wallId"></param>
        ///// <returns></returns>
        //private SCP_STATUS_T WallClose(SCP_WALLID_T wallId)
        //{
        //    SCP_BODY_T body = new SCP_BODY_T();
        //    body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_WALLCLOSE;
        //    var dataByte = Utils.StructToBytes(wallId);
        //    body.scp_datalen = (uint)dataByte.Count();
        //    body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

        //    SCP_HEADER_T header = new SCP_HEADER_T();
        //    header.scp_id = 0;
        //    header.scp_type = (ushort)ScpType.SCP_COMMAND;
        //    var bodyByte = Utils.StructToBytes(body);
        //    header.scp_datalen = (uint)bodyByte.Count();
        //    header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

        //    ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
        //    SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
        //    SCP_STATUS_T status = default(SCP_STATUS_T);
        //    if (response.scp_type == (ushort)ScpType.SCP_RETURN)
        //    {
        //        SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
        //        if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
        //        {
        //            status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
        //        }
        //    }
        //    return status;
        //}

        ///// <summary>
        ///// 打开墙体
        ///// </summary>
        ///// <param name="wallId"></param>
        ///// <returns></returns>
        //private SCP_STATUS_T WallOpen(SCP_WALLID_T wallId)
        //{
        //    SCP_BODY_T body = new SCP_BODY_T();
        //    body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_WALLOPEN;
        //    var dataByte = Utils.StructToBytes(wallId);
        //    body.scp_datalen = (uint)dataByte.Count();
        //    body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

        //    SCP_HEADER_T header = new SCP_HEADER_T();
        //    header.scp_id = 0;
        //    header.scp_type = (ushort)ScpType.SCP_COMMAND;
        //    var bodyByte = Utils.StructToBytes(body);
        //    header.scp_datalen = (uint)bodyByte.Count();
        //    header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

        //    ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
        //    SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
        //    SCP_STATUS_T status = default(SCP_STATUS_T);
        //    if (response.scp_type == (ushort)ScpType.SCP_RETURN)
        //    {
        //        SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
        //        if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
        //        {
        //            status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
        //        }
        //    }
        //    return status;
        //}

        ///// <summary>
        ///// 获取系统时间
        ///// </summary>
        ///// <param name="wallId"></param>
        ///// <returns></returns>
        //private SCP_DATETIME_T GetSystemTime(SCP_SENDERID_T senderId)
        //{
        //    SCP_BODY_T body = new SCP_BODY_T();
        //    body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_GET_SYSTIME;
        //    var dataByte = Utils.StructToBytes(senderId);
        //    body.scp_datalen = (uint)dataByte.Count();
        //    body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

        //    SCP_HEADER_T header = new SCP_HEADER_T();
        //    header.scp_id = 0;
        //    header.scp_type = (ushort)ScpType.SCP_COMMAND;
        //    var bodyByte = Utils.StructToBytes(body);
        //    header.scp_datalen = (uint)bodyByte.Count();
        //    header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

        //    ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
        //    SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
        //    SCP_DATETIME_T dateTime = default(SCP_DATETIME_T);
        //    if (response.scp_type == (ushort)ScpType.SCP_RETURN)
        //    {
        //        SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
        //        if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_GET_SYSTIME)
        //        {
        //            dateTime = (SCP_DATETIME_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_DATETIME_T));
        //        }
        //    }
        //    return dateTime;
        //}

        ///// <summary>
        ///// 获取发送器所有测试图片
        ///// </summary>
        ///// <param name="wallId"></param>
        ///// <returns></returns>
        //private SCP_GET_ALLTESTPIC_T GetAllTestPic(SCP_SENDERID_T senderId)
        //{
        //    SCP_BODY_T body = new SCP_BODY_T();
        //    body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_GET_ALLTESTPIC;
        //    var dataByte = Utils.StructToBytes(senderId);
        //    body.scp_datalen = (uint)dataByte.Count();
        //    body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

        //    SCP_HEADER_T header = new SCP_HEADER_T();
        //    header.scp_id = 0;
        //    header.scp_type = (ushort)ScpType.SCP_COMMAND;
        //    var bodyByte = Utils.StructToBytes(body);
        //    header.scp_datalen = (uint)bodyByte.Count();
        //    header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

        //    ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
        //    SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
        //    SCP_GET_ALLTESTPIC_T allTestPic = default(SCP_GET_ALLTESTPIC_T);
        //    if (response.scp_type == (ushort)ScpType.SCP_RETURN)
        //    {
        //        SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
        //        if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_GET_ALLTESTPIC)
        //        {
        //            allTestPic = (SCP_GET_ALLTESTPIC_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_GET_ALLTESTPIC_T));
        //        }
        //    }
        //    return allTestPic;
        //}

        ///// <summary>
        ///// 设置发送器测试图片
        ///// </summary>
        ///// <param name="wallId"></param>
        ///// <returns></returns>
        //private SCP_STATUS_T SetAllTestPic(SCP_SENDERID_T senderId)
        //{
        //    SCP_SET_TESTPIC_T setTestPic = new SCP_SET_TESTPIC_T();
        //    setTestPic.senderId = senderId;
        //    setTestPic.picId = 12;

        //    SCP_BODY_T body = new SCP_BODY_T();
        //    body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_SET_TESTPIC;
        //    var dataByte = Utils.StructToBytes(setTestPic);
        //    body.scp_datalen = (uint)dataByte.Count();
        //    body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

        //    SCP_HEADER_T header = new SCP_HEADER_T();
        //    header.scp_id = 0;
        //    header.scp_type = (ushort)ScpType.SCP_COMMAND;
        //    var bodyByte = Utils.StructToBytes(body);
        //    header.scp_datalen = (uint)bodyByte.Count();
        //    header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

        //    ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
        //    SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
        //    SCP_STATUS_T status = default(SCP_STATUS_T);
        //    if (response.scp_type == (ushort)ScpType.SCP_RETURN)
        //    {
        //        SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
        //        if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
        //        {
        //            status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
        //        }
        //    }
        //    return status;
        //}

        ///// <summary>
        ///// 设置模组测试图片
        ///// </summary>
        ///// <param name="wallId"></param>
        ///// <returns></returns>
        //private SCP_STATUS_T SetModTestPic(SCP_SENDERID_T senderId)
        //{
        //    SCP_SET_MODTESTPIC_T setModTestPic = new SCP_SET_MODTESTPIC_T();
        //    setModTestPic.senderId = senderId;
        //    setModTestPic.modGPId = 0;
        //    setModTestPic.picId = 3;

        //    SCP_BODY_T body = new SCP_BODY_T();
        //    body.scp_subtype = (ushort)ScpSubtype.SCP_CMD_SET_MODTESTPIC;
        //    var dataByte = Utils.StructToBytes(setModTestPic);
        //    body.scp_datalen = (uint)dataByte.Count();
        //    body.scp_data = dataByte.Concat(new byte[200 - body.scp_datalen]).ToArray();

        //    SCP_HEADER_T header = new SCP_HEADER_T();
        //    header.scp_id = 0;
        //    header.scp_type = (ushort)ScpType.SCP_COMMAND;
        //    var bodyByte = Utils.StructToBytes(body);
        //    header.scp_datalen = (uint)bodyByte.Count();
        //    header.scp_data = bodyByte.Concat(new byte[210 - header.scp_datalen]).ToArray();

        //    ICommunicationHandler communicationHandler = CommunicationHandlerFactory.Instance.ICommunicationHandler;
        //    SCP_HEADER_T response = communicationHandler.Handle<SCP_HEADER_T>(header);
        //    SCP_STATUS_T status = default(SCP_STATUS_T);
        //    if (response.scp_type == (ushort)ScpType.SCP_RETURN)
        //    {
        //        SCP_BODY_T a = (SCP_BODY_T)Utils.BytesToStruct(response.scp_data, typeof(SCP_BODY_T));
        //        if (a.scp_subtype == (ushort)ScpSubtype.SCP_RET_STATUS)
        //        {
        //            status = (SCP_STATUS_T)Utils.BytesToStruct(a.scp_data, typeof(SCP_STATUS_T));
        //        }
        //    }
        //    return status;
        //}
    }
}
